Merge remote-tracking branch 'origin' into eric/nova
* origin: (45 commits) Fix splash config (#2452) convert prefix to lowercase in actor autocomplete query (#2431) support intl tenor links (#2438) Splash: reduce motion + dark mode (#2448) Bump android app version code Don't use mask for android at all (#2445) Update Korean localization (#2432) Use android mode, fix fallback (#2437) Update for Version 1.63 Português (BR) (#2435) New translations messages.po (Ukrainian) (#2422) Update Japanese localization (addition + language code correction) (#2423) 1.63 Additional embed sources and external-media consent controls (#2424) Reduce web requests (#2420) New user home feed fixes (#2421) E2E runner fixes (#2428) Recompile all locales (#2411) (#2416) Add Ukrainian localization (#2336) Update Portuguese for Português (#2414) Add Portuguese Localization (#2407) ...
This commit is contained in:
+24
-3
@@ -1,5 +1,6 @@
|
||||
import {resolveConfig} from 'detox/internals'
|
||||
import {execSync} from 'child_process'
|
||||
import http from 'http'
|
||||
|
||||
const platform = device.getPlatform()
|
||||
|
||||
@@ -105,9 +106,29 @@ async function openAppForDebugBuild(platform: string, opts: any) {
|
||||
}
|
||||
|
||||
export async function createServer(path = '') {
|
||||
const res = await fetch(`http://localhost:1986/${path}`, {method: 'POST'})
|
||||
const resBody = await res.text()
|
||||
return resBody
|
||||
return new Promise(function (resolve, reject) {
|
||||
var req = http.request(
|
||||
{
|
||||
method: 'POST',
|
||||
host: 'localhost',
|
||||
port: 1986,
|
||||
path: `/${path}`,
|
||||
},
|
||||
function (res) {
|
||||
const body: Buffer[] = []
|
||||
res.on('data', chunk => body.push(chunk))
|
||||
res.on('end', function () {
|
||||
try {
|
||||
resolve(Buffer.concat(body).toString())
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
req.on('error', reject)
|
||||
req.end()
|
||||
})
|
||||
}
|
||||
|
||||
const getDeepLinkUrl = (url: string) =>
|
||||
|
||||
+268
-26
@@ -394,6 +394,7 @@ describe('parseEmbedPlayerFromUrl', () => {
|
||||
'https://youtube.com/watch?v=videoId',
|
||||
'https://youtube.com/watch?v=videoId&feature=share',
|
||||
'https://youtube.com/shorts/videoId',
|
||||
'https://m.youtube.com/watch?v=videoId',
|
||||
|
||||
'https://youtube.com/shorts/',
|
||||
'https://youtube.com/',
|
||||
@@ -401,113 +402,354 @@ describe('parseEmbedPlayerFromUrl', () => {
|
||||
|
||||
'https://twitch.tv/channelName',
|
||||
'https://www.twitch.tv/channelName',
|
||||
'https://m.twitch.tv/channelName',
|
||||
|
||||
'https://twitch.tv/channelName/clip/clipId',
|
||||
'https://twitch.tv/videos/videoId',
|
||||
|
||||
'https://open.spotify.com/playlist/playlistId',
|
||||
'https://open.spotify.com/playlist/playlistId?param=value',
|
||||
'https://open.spotify.com/locale/playlist/playlistId',
|
||||
|
||||
'https://open.spotify.com/track/songId',
|
||||
'https://open.spotify.com/track/songId?param=value',
|
||||
'https://open.spotify.com/locale/track/songId',
|
||||
|
||||
'https://open.spotify.com/album/albumId',
|
||||
'https://open.spotify.com/album/albumId?param=value',
|
||||
'https://open.spotify.com/locale/album/albumId',
|
||||
|
||||
'https://soundcloud.com/user/track',
|
||||
'https://soundcloud.com/user/sets/set',
|
||||
'https://soundcloud.com/user/',
|
||||
|
||||
'https://music.apple.com/us/playlist/playlistName/playlistId',
|
||||
'https://music.apple.com/us/album/albumName/albumId',
|
||||
'https://music.apple.com/us/album/albumName/albumId?i=songId',
|
||||
|
||||
'https://vimeo.com/videoId',
|
||||
'https://vimeo.com/videoId?autoplay=0',
|
||||
|
||||
'https://giphy.com/gifs/some-random-gif-name-gifId',
|
||||
'https://giphy.com/gif/some-random-gif-name-gifId',
|
||||
'https://giphy.com/gifs/',
|
||||
|
||||
'https://media.giphy.com/media/gifId/giphy.webp',
|
||||
'https://media0.giphy.com/media/gifId/giphy.webp',
|
||||
'https://media1.giphy.com/media/gifId/giphy.gif',
|
||||
'https://media2.giphy.com/media/gifId/giphy.webp',
|
||||
'https://media3.giphy.com/media/gifId/giphy.mp4',
|
||||
'https://media4.giphy.com/media/gifId/giphy.webp',
|
||||
'https://media5.giphy.com/media/gifId/giphy.mp4',
|
||||
'https://media0.giphy.com/media/gifId/giphy.mp3',
|
||||
'https://media1.google.com/media/gifId/giphy.webp',
|
||||
|
||||
'https://media.giphy.com/media/trackingId/gifId/giphy.webp',
|
||||
|
||||
'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
'https://i.giphy.com/gifId.gif',
|
||||
'https://i.giphy.com/gifId.gif',
|
||||
|
||||
'https://tenor.com/view/gifId',
|
||||
'https://tenor.com/notView/gifId',
|
||||
'https://tenor.com/view',
|
||||
'https://tenor.com/view/gifId.gif',
|
||||
'https://tenor.com/intl/view/gifId.gif',
|
||||
]
|
||||
|
||||
const outputs = [
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_short',
|
||||
source: 'youtubeShorts',
|
||||
hideDetails: true,
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
{
|
||||
type: 'youtube_video',
|
||||
videoId: 'videoId',
|
||||
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
|
||||
source: 'youtube',
|
||||
playerUri:
|
||||
'https://www.youtube.com/embed/videoId?autoplay=1&playsinline=1',
|
||||
},
|
||||
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
|
||||
{
|
||||
type: 'twitch_live',
|
||||
channelId: 'channelName',
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
||||
},
|
||||
{
|
||||
type: 'twitch_live',
|
||||
channelId: 'channelName',
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
||||
},
|
||||
{
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
|
||||
},
|
||||
{
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://clips.twitch.tv/embed?volume=0.5&autoplay=true&clip=clipId&parent=localhost`,
|
||||
},
|
||||
{
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&video=videoId&parent=localhost`,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'spotify_playlist',
|
||||
playlistId: 'playlistId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_playlist',
|
||||
playlistId: 'playlistId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_playlist',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'spotify_song',
|
||||
songId: 'songId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/track/songId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_song',
|
||||
songId: 'songId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/track/songId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_song',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/track/songId`,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'spotify_album',
|
||||
albumId: 'albumId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_album',
|
||||
albumId: 'albumId',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
||||
},
|
||||
{
|
||||
type: 'spotify_album',
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/album/albumId`,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'soundcloud_track',
|
||||
user: 'user',
|
||||
track: 'track',
|
||||
source: 'soundcloud',
|
||||
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/track&auto_play=true&visual=false&hide_related=true`,
|
||||
},
|
||||
{
|
||||
type: 'soundcloud_set',
|
||||
user: 'user',
|
||||
set: 'set',
|
||||
source: 'soundcloud',
|
||||
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/sets/set&auto_play=true&visual=false&hide_related=true`,
|
||||
},
|
||||
undefined,
|
||||
|
||||
{
|
||||
type: 'apple_music_playlist',
|
||||
source: 'appleMusic',
|
||||
playerUri:
|
||||
'https://embed.music.apple.com/us/playlist/playlistName/playlistId',
|
||||
},
|
||||
{
|
||||
type: 'apple_music_album',
|
||||
source: 'appleMusic',
|
||||
playerUri: 'https://embed.music.apple.com/us/album/albumName/albumId',
|
||||
},
|
||||
{
|
||||
type: 'apple_music_song',
|
||||
source: 'appleMusic',
|
||||
playerUri:
|
||||
'https://embed.music.apple.com/us/album/albumName/albumId?i=songId',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'vimeo_video',
|
||||
source: 'vimeo',
|
||||
playerUri: 'https://player.vimeo.com/video/videoId?autoplay=1',
|
||||
},
|
||||
{
|
||||
type: 'vimeo_video',
|
||||
source: 'vimeo',
|
||||
playerUri: 'https://player.vimeo.com/video/videoId?autoplay=1',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
{
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: 'https://giphy.com/gifs/gifId',
|
||||
playerUri: 'https://i.giphy.com/media/gifId/giphy.webp',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'tenor_gif',
|
||||
source: 'tenor',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
playerUri: 'https://tenor.com/view/gifId.gif',
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
type: 'tenor_gif',
|
||||
source: 'tenor',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
playerUri: 'https://tenor.com/view/gifId.gif',
|
||||
},
|
||||
{
|
||||
type: 'tenor_gif',
|
||||
source: 'tenor',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
playerUri: 'https://tenor.com/intl/view/gifId.gif',
|
||||
},
|
||||
]
|
||||
|
||||
it('correctly grabs the correct id from uri', () => {
|
||||
|
||||
+22
-7
@@ -1,5 +1,16 @@
|
||||
const pkg = require('./package.json')
|
||||
|
||||
const SPLASH_CONFIG = {
|
||||
backgroundColor: '#ffffff',
|
||||
image: './assets/splash.png',
|
||||
resizeMode: 'cover',
|
||||
}
|
||||
const DARK_SPLASH_CONFIG = {
|
||||
backgroundColor: '#001429',
|
||||
image: './assets/splash-dark.png',
|
||||
resizeMode: 'cover',
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
/**
|
||||
* App version number. Should be incremented as part of a release cycle.
|
||||
@@ -9,12 +20,12 @@ module.exports = function () {
|
||||
/**
|
||||
* iOS build number. Must be incremented for each TestFlight version.
|
||||
*/
|
||||
const IOS_BUILD_NUMBER = '2'
|
||||
const IOS_BUILD_NUMBER = '1'
|
||||
|
||||
/**
|
||||
* Android build number. Must be incremented for each release.
|
||||
*/
|
||||
const ANDROID_VERSION_CODE = 53
|
||||
const ANDROID_VERSION_CODE = 55
|
||||
|
||||
/**
|
||||
* Uses built-in Expo env vars
|
||||
@@ -42,11 +53,7 @@ module.exports = function () {
|
||||
orientation: 'portrait',
|
||||
icon: './assets/icon.png',
|
||||
userInterfaceStyle: 'automatic',
|
||||
splash: {
|
||||
image: './assets/splash.png',
|
||||
resizeMode: 'cover',
|
||||
backgroundColor: '#ffffff',
|
||||
},
|
||||
splash: SPLASH_CONFIG,
|
||||
ios: {
|
||||
buildNumber: IOS_BUILD_NUMBER,
|
||||
supportsTablet: false,
|
||||
@@ -66,6 +73,10 @@ module.exports = function () {
|
||||
'Used for profile pictures, posts, and other kinds of content',
|
||||
},
|
||||
associatedDomains: ['applinks:bsky.app', 'applinks:staging.bsky.app'],
|
||||
splash: {
|
||||
...SPLASH_CONFIG,
|
||||
dark: DARK_SPLASH_CONFIG,
|
||||
},
|
||||
},
|
||||
androidStatusBar: {
|
||||
barStyle: 'dark-content',
|
||||
@@ -95,6 +106,10 @@ module.exports = function () {
|
||||
category: ['BROWSABLE', 'DEFAULT'],
|
||||
},
|
||||
],
|
||||
splash: {
|
||||
...SPLASH_CONFIG,
|
||||
dark: DARK_SPLASH_CONFIG,
|
||||
},
|
||||
},
|
||||
web: {
|
||||
favicon: './assets/favicon.png',
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 991 KiB |
@@ -193,6 +193,7 @@ func serve(cctx *cli.Context) error {
|
||||
e.GET("/settings/home-feed", server.WebGeneric)
|
||||
e.GET("/settings/saved-feeds", server.WebGeneric)
|
||||
e.GET("/settings/threads", server.WebGeneric)
|
||||
e.GET("/settings/external-embeds", server.WebGeneric)
|
||||
e.GET("/sys/debug", server.WebGeneric)
|
||||
e.GET("/sys/log", server.WebGeneric)
|
||||
e.GET("/support", server.WebGeneric)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/** @type {import('@lingui/conf').LinguiConfig} */
|
||||
module.exports = {
|
||||
locales: ['en', 'hi', 'ja', 'fr', 'de', 'es'],
|
||||
locales: ['en', 'hi', 'ja', 'fr', 'de', 'es', 'ko', 'es', 'pt-BR', 'uk'],
|
||||
catalogs: [
|
||||
{
|
||||
path: '<rootDir>/src/locale/locales/{locale}/messages',
|
||||
|
||||
+3
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bsky.app",
|
||||
"version": "1.62.0",
|
||||
"version": "1.63.0",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -23,7 +23,7 @@
|
||||
"test-coverage": "NODE_ENV=test jest --coverage",
|
||||
"lint": "eslint ./src --ext .js,.jsx,.ts,.tsx",
|
||||
"typecheck": "tsc --project ./tsconfig.check.json",
|
||||
"e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node __e2e__/mock-server.ts",
|
||||
"e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts",
|
||||
"e2e:metro": "NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",
|
||||
"e2e:build": "NODE_ENV=test detox build -c ios.sim.debug",
|
||||
"e2e:run": "NODE_ENV=test detox test --configuration ios.sim.debug --take-screenshots all",
|
||||
@@ -158,7 +158,6 @@
|
||||
"react-native-root-siblings": "^4.1.1",
|
||||
"react-native-safe-area-context": "4.7.4",
|
||||
"react-native-screens": "~3.27.0",
|
||||
"react-native-splash-screen": "^3.3.0",
|
||||
"react-native-svg": "14.0.0",
|
||||
"react-native-url-polyfill": "^1.3.0",
|
||||
"react-native-uuid": "^2.0.1",
|
||||
@@ -167,7 +166,6 @@
|
||||
"react-native-web-linear-gradient": "^1.1.2",
|
||||
"react-native-web-webview": "^1.0.2",
|
||||
"react-native-webview": "^13.6.3",
|
||||
"react-native-youtube-iframe": "^2.3.0",
|
||||
"react-responsive": "^9.0.2",
|
||||
"rn-fetch-blob": "^0.12.0",
|
||||
"sentry-expo": "~7.0.1",
|
||||
@@ -216,7 +214,7 @@
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"babel-plugin-react-native-web": "^0.18.12",
|
||||
"babel-preset-expo": "^10.0.0",
|
||||
"detox": "^20.13.0",
|
||||
"detox": "^20.14.8",
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-plugin-detox": "^1.0.0",
|
||||
"eslint-plugin-ft-flow": "^2.0.3",
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
diff --git a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt
|
||||
index ff15c91..41aaf12 100644
|
||||
--- a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt
|
||||
+++ b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt
|
||||
@@ -26,51 +26,26 @@ import java.io.Serializable
|
||||
* @see [androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents]
|
||||
*/
|
||||
internal class ImageLibraryContract(
|
||||
- private val appContextProvider: AppContextProvider
|
||||
+ private val appContextProvider: AppContextProvider,
|
||||
) : AppContextActivityResultContract<ImageLibraryContractOptions, ImagePickerContractResult> {
|
||||
private val contentResolver: ContentResolver
|
||||
get() = appContextProvider.appContext.reactContext?.contentResolver
|
||||
?: throw Exceptions.ReactContextLost()
|
||||
|
||||
override fun createIntent(context: Context, input: ImageLibraryContractOptions): Intent {
|
||||
- val request = PickVisualMediaRequest.Builder()
|
||||
- .setMediaType(
|
||||
- when (input.options.mediaTypes) {
|
||||
- MediaTypes.VIDEOS -> {
|
||||
- PickVisualMedia.VideoOnly
|
||||
- }
|
||||
-
|
||||
- MediaTypes.IMAGES -> {
|
||||
- PickVisualMedia.ImageOnly
|
||||
- }
|
||||
-
|
||||
- else -> {
|
||||
- PickVisualMedia.ImageAndVideo
|
||||
- }
|
||||
- }
|
||||
- )
|
||||
- .build()
|
||||
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
+ .addCategory(Intent.CATEGORY_OPENABLE)
|
||||
+ .setType("image/*")
|
||||
|
||||
if (input.options.allowsMultipleSelection) {
|
||||
- val selectionLimit = input.options.selectionLimit
|
||||
-
|
||||
- if (selectionLimit == 1) {
|
||||
- // If multiple selection is allowed but the limit is 1, we should ignore
|
||||
- // the multiple selection flag and just treat it as a single selection.
|
||||
- return PickVisualMedia().createIntent(context, request)
|
||||
+ if(input.options.selectionLimit == 1) {
|
||||
+ return intent
|
||||
}
|
||||
|
||||
- if (selectionLimit > 1) {
|
||||
- return PickMultipleVisualMedia(selectionLimit).createIntent(context, request)
|
||||
- }
|
||||
-
|
||||
- // If the selection limit is 0, it is the same as unlimited selection.
|
||||
- if (selectionLimit == UNLIMITED_SELECTION) {
|
||||
- return PickMultipleVisualMedia().createIntent(context, request)
|
||||
- }
|
||||
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
|
||||
}
|
||||
|
||||
- return PickVisualMedia().createIntent(context, request)
|
||||
+ return intent
|
||||
}
|
||||
|
||||
override fun parseResult(input: ImageLibraryContractOptions, resultCode: Int, intent: Intent?) =
|
||||
@@ -0,0 +1,3 @@
|
||||
added by https://github.com/bluesky-social/social-app/pull/2384#pullrequestreview-1800985521
|
||||
|
||||
hackfixes the image picker on android so that the user can select from their typical image sources
|
||||
@@ -74,6 +74,7 @@ import {ModerationBlockedAccounts} from 'view/screens/ModerationBlockedAccounts'
|
||||
import {SavedFeeds} from 'view/screens/SavedFeeds'
|
||||
import {PreferencesHomeFeed} from 'view/screens/PreferencesHomeFeed'
|
||||
import {PreferencesThreads} from 'view/screens/PreferencesThreads'
|
||||
import {PreferencesExternalEmbeds} from '#/view/screens/PreferencesExternalEmbeds'
|
||||
import {createNativeStackNavigatorWithAuth} from './view/shell/createNativeStackNavigatorWithAuth'
|
||||
|
||||
const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
|
||||
@@ -243,6 +244,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
|
||||
getComponent={() => PreferencesThreads}
|
||||
options={{title: title('Threads Preferences'), requireAuth: true}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="PreferencesExternalEmbeds"
|
||||
getComponent={() => PreferencesExternalEmbeds}
|
||||
options={{
|
||||
title: title('External Media Preferences'),
|
||||
requireAuth: true,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
+151
-63
@@ -1,5 +1,11 @@
|
||||
import React, {useCallback, useEffect} from 'react'
|
||||
import {View, StyleSheet, Image as RNImage} from 'react-native'
|
||||
import {
|
||||
View,
|
||||
StyleSheet,
|
||||
Image as RNImage,
|
||||
AccessibilityInfo,
|
||||
useColorScheme,
|
||||
} from 'react-native'
|
||||
import * as SplashScreen from 'expo-splash-screen'
|
||||
import {Image} from 'expo-image'
|
||||
import Animated, {
|
||||
@@ -14,9 +20,18 @@ import MaskedView from '@react-native-masked-view/masked-view'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import Svg, {Path, SvgProps} from 'react-native-svg'
|
||||
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useColorMode} from 'state/shell'
|
||||
import {colors} from '#/lib/styles'
|
||||
|
||||
// @ts-ignore
|
||||
import splashImagePointer from '../assets/splash.png'
|
||||
// @ts-ignore
|
||||
import darkSplashImagePointer from '../assets/splash-dark.png'
|
||||
const splashImageUri = RNImage.resolveAssetSource(splashImagePointer).uri
|
||||
const darkSplashImageUri = RNImage.resolveAssetSource(
|
||||
darkSplashImagePointer,
|
||||
).uri
|
||||
|
||||
export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) {
|
||||
const width = 1000
|
||||
@@ -27,9 +42,9 @@ export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) {
|
||||
// @ts-ignore it's fiiiiine
|
||||
ref={ref}
|
||||
viewBox="0 0 64 66"
|
||||
style={{width, height}}>
|
||||
style={[{width, height}, props.style]}>
|
||||
<Path
|
||||
fill="#fff"
|
||||
fill={props.fill || '#fff'}
|
||||
d="M13.873 3.77C21.21 9.243 29.103 20.342 32 26.3v15.732c0-.335-.13.043-.41.858-1.512 4.414-7.418 21.642-20.923 7.87-7.111-7.252-3.819-14.503 9.125-16.692-7.405 1.252-15.73-.817-18.014-8.93C1.12 22.804 0 8.431 0 6.488 0-3.237 8.579-.18 13.873 3.77ZM50.127 3.77C42.79 9.243 34.897 20.342 32 26.3v15.732c0-.335.13.043.41.858 1.512 4.414 7.418 21.642 20.923 7.87 7.111-7.252 3.819-14.503-9.125-16.692 7.405 1.252 15.73-.817 18.014-8.93C62.88 22.804 64 8.431 64 6.488 64-3.237 55.422-.18 50.127 3.77Z"
|
||||
/>
|
||||
</Svg>
|
||||
@@ -50,9 +65,22 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
const outroAppOpacity = useSharedValue(0)
|
||||
const [isAnimationComplete, setIsAnimationComplete] = React.useState(false)
|
||||
const [isImageLoaded, setIsImageLoaded] = React.useState(false)
|
||||
const isReady = props.isReady && isImageLoaded
|
||||
const [isLayoutReady, setIsLayoutReady] = React.useState(false)
|
||||
const [reduceMotion, setReduceMotion] = React.useState<boolean | undefined>(
|
||||
false,
|
||||
)
|
||||
const isReady =
|
||||
props.isReady &&
|
||||
isImageLoaded &&
|
||||
isLayoutReady &&
|
||||
reduceMotion !== undefined
|
||||
|
||||
const logoAnimations = useAnimatedStyle(() => {
|
||||
const colorMode = useColorMode()
|
||||
const colorScheme = useColorScheme()
|
||||
const themeName = colorMode === 'system' ? colorScheme : colorMode
|
||||
const isDarkMode = themeName === 'dark'
|
||||
|
||||
const logoAnimation = useAnimatedStyle(() => {
|
||||
return {
|
||||
transform: [
|
||||
{
|
||||
@@ -62,7 +90,7 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
scale: interpolate(
|
||||
outroLogo.value,
|
||||
[0, 0.08, 1],
|
||||
[1, 0.8, 400],
|
||||
[1, 0.8, 500],
|
||||
'clamp',
|
||||
),
|
||||
},
|
||||
@@ -70,6 +98,27 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'),
|
||||
}
|
||||
})
|
||||
const reducedLogoAnimation = useAnimatedStyle(() => {
|
||||
return {
|
||||
transform: [
|
||||
{
|
||||
scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'),
|
||||
},
|
||||
],
|
||||
opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'),
|
||||
}
|
||||
})
|
||||
|
||||
const logoWrapperAnimation = useAnimatedStyle(() => {
|
||||
return {
|
||||
opacity: interpolate(
|
||||
outroAppOpacity.value,
|
||||
[0, 0.1, 0.2, 1],
|
||||
[1, 1, 0, 0],
|
||||
'clamp',
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
const appAnimation = useAnimatedStyle(() => {
|
||||
return {
|
||||
@@ -80,7 +129,7 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
],
|
||||
opacity: interpolate(
|
||||
outroAppOpacity.value,
|
||||
[0, 0.08, 0.15, 1],
|
||||
[0, 0.1, 0.2, 1],
|
||||
[0, 0, 1, 1],
|
||||
'clamp',
|
||||
),
|
||||
@@ -88,82 +137,121 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
})
|
||||
|
||||
const onFinish = useCallback(() => setIsAnimationComplete(true), [])
|
||||
const onLayout = useCallback(() => setIsLayoutReady(true), [])
|
||||
const onLoadEnd = useCallback(() => setIsImageLoaded(true), [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isReady) {
|
||||
// hide on mount
|
||||
SplashScreen.hideAsync().catch(() => {})
|
||||
|
||||
intro.value = withTiming(
|
||||
1,
|
||||
{duration: 400, easing: Easing.out(Easing.cubic)},
|
||||
async () => {
|
||||
// set these values to check animation at specific point
|
||||
// outroLogo.value = 0.1
|
||||
// outroApp.value = 0.1
|
||||
outroLogo.value = withTiming(
|
||||
SplashScreen.hideAsync()
|
||||
.then(() => {
|
||||
intro.value = withTiming(
|
||||
1,
|
||||
{duration: 1200, easing: Easing.in(Easing.cubic)},
|
||||
() => {
|
||||
runOnJS(onFinish)()
|
||||
{duration: 400, easing: Easing.out(Easing.cubic)},
|
||||
async () => {
|
||||
// set these values to check animation at specific point
|
||||
// outroLogo.value = 0.1
|
||||
// outroApp.value = 0.1
|
||||
outroLogo.value = withTiming(
|
||||
1,
|
||||
{duration: 1200, easing: Easing.in(Easing.cubic)},
|
||||
() => {
|
||||
runOnJS(onFinish)()
|
||||
},
|
||||
)
|
||||
outroApp.value = withTiming(1, {
|
||||
duration: 1200,
|
||||
easing: Easing.inOut(Easing.cubic),
|
||||
})
|
||||
outroAppOpacity.value = withTiming(1, {
|
||||
duration: 1200,
|
||||
easing: Easing.in(Easing.cubic),
|
||||
})
|
||||
},
|
||||
)
|
||||
outroApp.value = withTiming(1, {
|
||||
duration: 1200,
|
||||
easing: Easing.inOut(Easing.cubic),
|
||||
})
|
||||
outroAppOpacity.value = withTiming(1, {
|
||||
duration: 1200,
|
||||
easing: Easing.in(Easing.cubic),
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
}, [onFinish, intro, outroLogo, outroApp, outroAppOpacity, isReady])
|
||||
|
||||
const onLoadEnd = useCallback(() => {
|
||||
setIsImageLoaded(true)
|
||||
}, [setIsImageLoaded])
|
||||
useEffect(() => {
|
||||
AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion)
|
||||
}, [])
|
||||
|
||||
const logoAnimations =
|
||||
reduceMotion === true ? reducedLogoAnimation : logoAnimation
|
||||
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<View style={{flex: 1}} onLayout={onLayout}>
|
||||
{!isAnimationComplete && (
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors
|
||||
onLoadEnd={onLoadEnd}
|
||||
source={{uri: splashImageUri}}
|
||||
source={{uri: isDarkMode ? darkSplashImageUri : splashImageUri}}
|
||||
style={StyleSheet.absoluteFillObject}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MaskedView
|
||||
style={[StyleSheet.absoluteFillObject]}
|
||||
maskElement={
|
||||
<Animated.View
|
||||
style={[
|
||||
StyleSheet.absoluteFillObject,
|
||||
{
|
||||
// Transparent background because mask is based off alpha channel.
|
||||
backgroundColor: 'transparent',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
transform: [{translateY: -(insets.top / 2)}, {scale: 0.1}], // scale from 1000px to 100px
|
||||
},
|
||||
]}>
|
||||
<AnimatedLogo style={[logoAnimations]} />
|
||||
</Animated.View>
|
||||
}>
|
||||
{!isAnimationComplete && (
|
||||
<View
|
||||
style={[StyleSheet.absoluteFillObject, {backgroundColor: 'white'}]}
|
||||
/>
|
||||
)}
|
||||
{isReady &&
|
||||
(isAndroid || reduceMotion === true ? (
|
||||
// Use a simple fade on older versions of android (work around a bug)
|
||||
<>
|
||||
<Animated.View style={[{flex: 1}, appAnimation]}>
|
||||
{props.children}
|
||||
</Animated.View>
|
||||
|
||||
<Animated.View style={[{flex: 1}, appAnimation]}>
|
||||
{props.children}
|
||||
</Animated.View>
|
||||
</MaskedView>
|
||||
{!isAnimationComplete && (
|
||||
<Animated.View
|
||||
style={[
|
||||
StyleSheet.absoluteFillObject,
|
||||
logoWrapperAnimation,
|
||||
{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
transform: [{translateY: -(insets.top / 2)}, {scale: 0.1}], // scale from 1000px to 100px
|
||||
},
|
||||
]}>
|
||||
<AnimatedLogo
|
||||
fill={isDarkMode ? colors.blue3 : '#fff'}
|
||||
style={[{opacity: 0}, logoAnimations]}
|
||||
/>
|
||||
</Animated.View>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<MaskedView
|
||||
style={[StyleSheet.absoluteFillObject]}
|
||||
maskElement={
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
// Transparent background because mask is based off alpha channel.
|
||||
backgroundColor: 'transparent',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
transform: [{translateY: -(insets.top / 2)}, {scale: 0.1}], // scale from 1000px to 100px
|
||||
},
|
||||
]}>
|
||||
<AnimatedLogo
|
||||
fill={isDarkMode ? colors.blue3 : '#fff'}
|
||||
style={[logoAnimations]}
|
||||
/>
|
||||
</Animated.View>
|
||||
}>
|
||||
{!isAnimationComplete && (
|
||||
<View
|
||||
style={[
|
||||
StyleSheet.absoluteFillObject,
|
||||
{backgroundColor: isDarkMode ? colors.blue3 : '#fff'},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
<Animated.View style={[{flex: 1}, appAnimation]}>
|
||||
{props.children}
|
||||
</Animated.View>
|
||||
</MaskedView>
|
||||
))}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ interface ScreenPropertiesMap {
|
||||
Settings: {}
|
||||
AppPasswords: {}
|
||||
Moderation: {}
|
||||
PreferencesExternalEmbeds: {}
|
||||
BlockedAccounts: {}
|
||||
MutedAccounts: {}
|
||||
SavedFeeds: {}
|
||||
|
||||
@@ -98,7 +98,7 @@ export class MergeFeedAPI implements FeedAPI {
|
||||
}
|
||||
|
||||
return {
|
||||
cursor: posts.length ? String(this.itemCursor) : undefined,
|
||||
cursor: String(this.itemCursor),
|
||||
feed: posts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export function IS_LOCAL_DEV(url: string) {
|
||||
}
|
||||
|
||||
export function IS_STAGING(url: string) {
|
||||
return !IS_LOCAL_DEV(url) && !IS_PROD(url)
|
||||
return url.startsWith('https://staging.bsky.dev')
|
||||
}
|
||||
|
||||
export function IS_PROD(url: string) {
|
||||
@@ -51,7 +51,8 @@ export function IS_PROD(url: string) {
|
||||
// -prf
|
||||
return (
|
||||
url.startsWith('https://bsky.social') ||
|
||||
url.startsWith('https://api.bsky.app')
|
||||
url.startsWith('https://api.bsky.app') ||
|
||||
/bsky\.network\/?$/.test(url)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -116,8 +117,8 @@ export async function DEFAULT_FEEDS(
|
||||
} else {
|
||||
// production
|
||||
return {
|
||||
pinned: [],
|
||||
saved: [],
|
||||
pinned: [PROD_DEFAULT_FEED('whats-hot')],
|
||||
saved: [PROD_DEFAULT_FEED('whats-hot')],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {BskyAgent} from '@atproto/api'
|
||||
import {isBskyAppUrl} from '../strings/url-helpers'
|
||||
import {extractBskyMeta} from './bsky'
|
||||
import {LINK_META_PROXY} from 'lib/constants'
|
||||
import {getGiphyMetaUri} from 'lib/strings/embed-player'
|
||||
|
||||
export enum LikelyType {
|
||||
HTML,
|
||||
@@ -34,6 +35,13 @@ export async function getLinkMeta(
|
||||
let urlp
|
||||
try {
|
||||
urlp = new URL(url)
|
||||
|
||||
// Get Giphy meta uri if this is any form of giphy link
|
||||
const giphyMetaUri = getGiphyMetaUri(urlp)
|
||||
if (giphyMetaUri) {
|
||||
url = giphyMetaUri
|
||||
urlp = new URL(url)
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
error: 'Invalid URL',
|
||||
|
||||
@@ -117,9 +117,6 @@ function createResizedImage(
|
||||
return reject(new Error('Failed to resize image'))
|
||||
}
|
||||
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
|
||||
let scale = 1
|
||||
if (mode === 'cover') {
|
||||
scale = img.width < img.height ? width / img.width : height / img.height
|
||||
@@ -128,10 +125,11 @@ function createResizedImage(
|
||||
}
|
||||
let w = img.width * scale
|
||||
let h = img.height * scale
|
||||
let x = (width - w) / 2
|
||||
let y = (height - h) / 2
|
||||
|
||||
ctx.drawImage(img, x, y, w, h)
|
||||
canvas.width = w
|
||||
canvas.height = h
|
||||
|
||||
ctx.drawImage(img, 0, 0, w, h)
|
||||
resolve(canvas.toDataURL('image/jpeg', quality))
|
||||
})
|
||||
img.src = dataUri
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
MediaTypeOptions,
|
||||
} from 'expo-image-picker'
|
||||
import {getDataUriSize} from './util'
|
||||
import * as Toast from 'view/com/util/Toast'
|
||||
|
||||
export async function openPicker(opts?: ImagePickerOptions) {
|
||||
const response = await launchImageLibraryAsync({
|
||||
@@ -13,7 +14,11 @@ export async function openPicker(opts?: ImagePickerOptions) {
|
||||
...opts,
|
||||
})
|
||||
|
||||
return (response.assets ?? []).map(image => ({
|
||||
if (response.assets && response.assets.length > 4) {
|
||||
Toast.show('You may only select up to 4 images')
|
||||
}
|
||||
|
||||
return (response.assets ?? []).slice(0, 4).map(image => ({
|
||||
mime: 'image/jpeg',
|
||||
height: image.height,
|
||||
width: image.width,
|
||||
|
||||
@@ -32,6 +32,7 @@ export type CommonNavigatorParams = {
|
||||
SavedFeeds: undefined
|
||||
PreferencesHomeFeed: undefined
|
||||
PreferencesThreads: undefined
|
||||
PreferencesExternalEmbeds: undefined
|
||||
}
|
||||
|
||||
export type BottomTabNavigatorParams = CommonNavigatorParams & {
|
||||
|
||||
+297
-46
@@ -1,17 +1,59 @@
|
||||
import {Platform} from 'react-native'
|
||||
import {Dimensions, Platform} from 'react-native'
|
||||
const {height: SCREEN_HEIGHT} = Dimensions.get('window')
|
||||
|
||||
export type EmbedPlayerParams =
|
||||
| {type: 'youtube_video'; videoId: string; playerUri: string}
|
||||
| {type: 'twitch_live'; channelId: string; playerUri: string}
|
||||
| {type: 'spotify_album'; albumId: string; playerUri: string}
|
||||
| {
|
||||
type: 'spotify_playlist'
|
||||
playlistId: string
|
||||
playerUri: string
|
||||
}
|
||||
| {type: 'spotify_song'; songId: string; playerUri: string}
|
||||
| {type: 'soundcloud_track'; user: string; track: string; playerUri: string}
|
||||
| {type: 'soundcloud_set'; user: string; set: string; playerUri: string}
|
||||
export const embedPlayerSources = [
|
||||
'youtube',
|
||||
'youtubeShorts',
|
||||
'twitch',
|
||||
'spotify',
|
||||
'soundcloud',
|
||||
'appleMusic',
|
||||
'vimeo',
|
||||
'giphy',
|
||||
'tenor',
|
||||
] as const
|
||||
|
||||
export type EmbedPlayerSource = (typeof embedPlayerSources)[number]
|
||||
|
||||
export type EmbedPlayerType =
|
||||
| 'youtube_video'
|
||||
| 'youtube_short'
|
||||
| 'twitch_video'
|
||||
| 'spotify_album'
|
||||
| 'spotify_playlist'
|
||||
| 'spotify_song'
|
||||
| 'soundcloud_track'
|
||||
| 'soundcloud_set'
|
||||
| 'apple_music_playlist'
|
||||
| 'apple_music_album'
|
||||
| 'apple_music_song'
|
||||
| 'vimeo_video'
|
||||
| 'giphy_gif'
|
||||
| 'tenor_gif'
|
||||
|
||||
export const externalEmbedLabels: Record<EmbedPlayerSource, string> = {
|
||||
youtube: 'YouTube',
|
||||
youtubeShorts: 'YouTube Shorts',
|
||||
vimeo: 'Vimeo',
|
||||
twitch: 'Twitch',
|
||||
giphy: 'GIPHY',
|
||||
tenor: 'Tenor',
|
||||
spotify: 'Spotify',
|
||||
appleMusic: 'Apple Music',
|
||||
soundcloud: 'SoundCloud',
|
||||
}
|
||||
|
||||
export interface EmbedPlayerParams {
|
||||
type: EmbedPlayerType
|
||||
playerUri: string
|
||||
isGif?: boolean
|
||||
source: EmbedPlayerSource
|
||||
metaUri?: string
|
||||
hideDetails?: boolean
|
||||
}
|
||||
|
||||
const giphyRegex = /media(?:[0-4]\.giphy\.com|\.giphy\.com)/i
|
||||
const gifFilenameRegex = /^(\S+)\.(webp|gif|mp4)$/i
|
||||
|
||||
export function parseEmbedPlayerFromUrl(
|
||||
url: string,
|
||||
@@ -29,63 +71,88 @@ export function parseEmbedPlayerFromUrl(
|
||||
if (videoId) {
|
||||
return {
|
||||
type: 'youtube_video',
|
||||
videoId,
|
||||
playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1`,
|
||||
source: 'youtube',
|
||||
playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1&playsinline=1`,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (urlp.hostname === 'www.youtube.com' || urlp.hostname === 'youtube.com') {
|
||||
if (
|
||||
urlp.hostname === 'www.youtube.com' ||
|
||||
urlp.hostname === 'youtube.com' ||
|
||||
urlp.hostname === 'm.youtube.com'
|
||||
) {
|
||||
const [_, page, shortVideoId] = urlp.pathname.split('/')
|
||||
const videoId =
|
||||
page === 'shorts' ? shortVideoId : (urlp.searchParams.get('v') as string)
|
||||
|
||||
if (videoId) {
|
||||
return {
|
||||
type: 'youtube_video',
|
||||
videoId,
|
||||
playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1`,
|
||||
type: page === 'shorts' ? 'youtube_short' : 'youtube_video',
|
||||
source: page === 'shorts' ? 'youtubeShorts' : 'youtube',
|
||||
hideDetails: page === 'shorts' ? true : undefined,
|
||||
playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1&playsinline=1`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// twitch
|
||||
if (urlp.hostname === 'twitch.tv' || urlp.hostname === 'www.twitch.tv') {
|
||||
if (
|
||||
urlp.hostname === 'twitch.tv' ||
|
||||
urlp.hostname === 'www.twitch.tv' ||
|
||||
urlp.hostname === 'm.twitch.tv'
|
||||
) {
|
||||
const parent =
|
||||
Platform.OS === 'web' ? window.location.hostname : 'localhost'
|
||||
|
||||
const parts = urlp.pathname.split('/')
|
||||
if (parts.length === 2 && parts[1]) {
|
||||
const [_, channelOrVideo, clipOrId, id] = urlp.pathname.split('/')
|
||||
|
||||
if (channelOrVideo === 'videos') {
|
||||
return {
|
||||
type: 'twitch_live',
|
||||
channelId: parts[1],
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=${parts[1]}&parent=${parent}`,
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&video=${clipOrId}&parent=${parent}`,
|
||||
}
|
||||
} else if (clipOrId === 'clip') {
|
||||
return {
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://clips.twitch.tv/embed?volume=0.5&autoplay=true&clip=${id}&parent=${parent}`,
|
||||
}
|
||||
} else if (channelOrVideo) {
|
||||
return {
|
||||
type: 'twitch_video',
|
||||
source: 'twitch',
|
||||
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=${channelOrVideo}&parent=${parent}`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// spotify
|
||||
if (urlp.hostname === 'open.spotify.com') {
|
||||
const [_, type, id] = urlp.pathname.split('/')
|
||||
if (type && id) {
|
||||
if (type === 'playlist') {
|
||||
const [_, typeOrLocale, idOrType, id] = urlp.pathname.split('/')
|
||||
|
||||
if (idOrType) {
|
||||
if (typeOrLocale === 'playlist' || idOrType === 'playlist') {
|
||||
return {
|
||||
type: 'spotify_playlist',
|
||||
playlistId: id,
|
||||
playerUri: `https://open.spotify.com/embed/playlist/${id}`,
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/playlist/${
|
||||
id ?? idOrType
|
||||
}`,
|
||||
}
|
||||
}
|
||||
if (type === 'album') {
|
||||
if (typeOrLocale === 'album' || idOrType === 'album') {
|
||||
return {
|
||||
type: 'spotify_album',
|
||||
albumId: id,
|
||||
playerUri: `https://open.spotify.com/embed/album/${id}`,
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/album/${id ?? idOrType}`,
|
||||
}
|
||||
}
|
||||
if (type === 'track') {
|
||||
if (typeOrLocale === 'track' || idOrType === 'track') {
|
||||
return {
|
||||
type: 'spotify_song',
|
||||
songId: id,
|
||||
playerUri: `https://open.spotify.com/embed/track/${id}`,
|
||||
source: 'spotify',
|
||||
playerUri: `https://open.spotify.com/embed/track/${id ?? idOrType}`,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,20 +169,173 @@ export function parseEmbedPlayerFromUrl(
|
||||
if (trackOrSets === 'sets' && set) {
|
||||
return {
|
||||
type: 'soundcloud_set',
|
||||
user,
|
||||
set: set,
|
||||
source: 'soundcloud',
|
||||
playerUri: `https://w.soundcloud.com/player/?url=${url}&auto_play=true&visual=false&hide_related=true`,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'soundcloud_track',
|
||||
user,
|
||||
track: trackOrSets,
|
||||
source: 'soundcloud',
|
||||
playerUri: `https://w.soundcloud.com/player/?url=${url}&auto_play=true&visual=false&hide_related=true`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
urlp.hostname === 'music.apple.com' ||
|
||||
urlp.hostname === 'music.apple.com'
|
||||
) {
|
||||
// This should always have: locale, type (playlist or album), name, and id. We won't use spread since we want
|
||||
// to check if the length is correct
|
||||
const pathParams = urlp.pathname.split('/')
|
||||
const type = pathParams[2]
|
||||
const songId = urlp.searchParams.get('i')
|
||||
|
||||
if (pathParams.length === 5 && (type === 'playlist' || type === 'album')) {
|
||||
// We want to append the songId to the end of the url if it exists
|
||||
const embedUri = `https://embed.music.apple.com${urlp.pathname}${
|
||||
urlp.search ? '?i=' + songId : ''
|
||||
}`
|
||||
|
||||
if (type === 'playlist') {
|
||||
return {
|
||||
type: 'apple_music_playlist',
|
||||
source: 'appleMusic',
|
||||
playerUri: embedUri,
|
||||
}
|
||||
} else if (type === 'album') {
|
||||
if (songId) {
|
||||
return {
|
||||
type: 'apple_music_song',
|
||||
source: 'appleMusic',
|
||||
playerUri: embedUri,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
type: 'apple_music_album',
|
||||
source: 'appleMusic',
|
||||
playerUri: embedUri,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (urlp.hostname === 'vimeo.com' || urlp.hostname === 'www.vimeo.com') {
|
||||
const [_, videoId] = urlp.pathname.split('/')
|
||||
if (videoId) {
|
||||
return {
|
||||
type: 'vimeo_video',
|
||||
source: 'vimeo',
|
||||
playerUri: `https://player.vimeo.com/video/${videoId}?autoplay=1`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (urlp.hostname === 'giphy.com' || urlp.hostname === 'www.giphy.com') {
|
||||
const [_, gifs, nameAndId] = urlp.pathname.split('/')
|
||||
|
||||
/*
|
||||
* nameAndId is a string that consists of the name (dash separated) and the id of the gif (the last part of the name)
|
||||
* We want to get the id of the gif, then direct to media.giphy.com/media/{id}/giphy.webp so we can
|
||||
* use it in an <Image> component
|
||||
*/
|
||||
|
||||
if (gifs === 'gifs' && nameAndId) {
|
||||
const gifId = nameAndId.split('-').pop()
|
||||
|
||||
if (gifId) {
|
||||
return {
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: `https://giphy.com/gifs/${gifId}`,
|
||||
playerUri: `https://i.giphy.com/media/${gifId}/giphy.webp`,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There are five possible hostnames that also can be giphy urls: media.giphy.com and media0-4.giphy.com
|
||||
// These can include (presumably) a tracking id in the path name, so we have to check for that as well
|
||||
if (giphyRegex.test(urlp.hostname)) {
|
||||
// We can link directly to the gif, if its a proper link
|
||||
const [_, media, trackingOrId, idOrFilename, filename] =
|
||||
urlp.pathname.split('/')
|
||||
|
||||
if (media === 'media') {
|
||||
if (idOrFilename && gifFilenameRegex.test(idOrFilename)) {
|
||||
return {
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: `https://giphy.com/gifs/${trackingOrId}`,
|
||||
playerUri: `https://i.giphy.com/media/${trackingOrId}/giphy.webp`,
|
||||
}
|
||||
} else if (filename && gifFilenameRegex.test(filename)) {
|
||||
return {
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: `https://giphy.com/gifs/${idOrFilename}`,
|
||||
playerUri: `https://i.giphy.com/media/${idOrFilename}/giphy.webp`,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, we should see if it is a link to i.giphy.com. These links don't necessarily end in .gif but can also
|
||||
// be .webp
|
||||
if (urlp.hostname === 'i.giphy.com' || urlp.hostname === 'www.i.giphy.com') {
|
||||
const [_, mediaOrFilename, filename] = urlp.pathname.split('/')
|
||||
|
||||
if (mediaOrFilename === 'media' && filename) {
|
||||
const gifId = filename.split('.')[0]
|
||||
return {
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: `https://giphy.com/gifs/${gifId}`,
|
||||
playerUri: `https://i.giphy.com/media/${gifId}/giphy.webp`,
|
||||
}
|
||||
} else if (mediaOrFilename) {
|
||||
const gifId = mediaOrFilename.split('.')[0]
|
||||
return {
|
||||
type: 'giphy_gif',
|
||||
source: 'giphy',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
metaUri: `https://giphy.com/gifs/${gifId}`,
|
||||
playerUri: `https://i.giphy.com/media/${
|
||||
mediaOrFilename.split('.')[0]
|
||||
}/giphy.webp`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (urlp.hostname === 'tenor.com' || urlp.hostname === 'www.tenor.com') {
|
||||
const [_, pathOrIntl, pathOrFilename, intlFilename] =
|
||||
urlp.pathname.split('/')
|
||||
const isIntl = pathOrFilename === 'view'
|
||||
const filename = isIntl ? intlFilename : pathOrFilename
|
||||
|
||||
if ((pathOrIntl === 'view' || pathOrFilename === 'view') && filename) {
|
||||
const includesExt = filename.split('.').pop() === 'gif'
|
||||
|
||||
return {
|
||||
type: 'tenor_gif',
|
||||
source: 'tenor',
|
||||
isGif: true,
|
||||
hideDetails: true,
|
||||
playerUri: `${url}${!includesExt ? '.gif' : ''}`,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getPlayerHeight({
|
||||
@@ -131,22 +351,53 @@ export function getPlayerHeight({
|
||||
|
||||
switch (type) {
|
||||
case 'youtube_video':
|
||||
case 'twitch_live':
|
||||
case 'twitch_video':
|
||||
case 'vimeo_video':
|
||||
return (width / 16) * 9
|
||||
case 'youtube_short':
|
||||
if (SCREEN_HEIGHT < 600) {
|
||||
return ((width / 9) * 16) / 1.75
|
||||
} else {
|
||||
return ((width / 9) * 16) / 1.5
|
||||
}
|
||||
case 'spotify_album':
|
||||
return 380
|
||||
case 'apple_music_album':
|
||||
case 'apple_music_playlist':
|
||||
case 'spotify_playlist':
|
||||
return 360
|
||||
case 'soundcloud_set':
|
||||
return 380
|
||||
case 'spotify_song':
|
||||
if (width <= 300) {
|
||||
return 180
|
||||
return 155
|
||||
}
|
||||
return 232
|
||||
case 'soundcloud_track':
|
||||
return 165
|
||||
case 'soundcloud_set':
|
||||
return 360
|
||||
case 'apple_music_song':
|
||||
return 150
|
||||
default:
|
||||
return width
|
||||
}
|
||||
}
|
||||
|
||||
export function getGifDims(
|
||||
originalHeight: number,
|
||||
originalWidth: number,
|
||||
viewWidth: number,
|
||||
) {
|
||||
const scaledHeight = (originalHeight / originalWidth) * viewWidth
|
||||
|
||||
return {
|
||||
height: scaledHeight > 250 ? 250 : scaledHeight,
|
||||
width: (250 / scaledHeight) * viewWidth,
|
||||
}
|
||||
}
|
||||
|
||||
export function getGiphyMetaUri(url: URL) {
|
||||
if (giphyRegex.test(url.hostname) || url.hostname === 'i.giphy.com') {
|
||||
const params = parseEmbedPlayerFromUrl(url.toString())
|
||||
if (params && params.type === 'giphy_gif') {
|
||||
return params.metaUri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ export const s = StyleSheet.create({
|
||||
flexGrow1: {flexGrow: 1},
|
||||
alignCenter: {alignItems: 'center'},
|
||||
alignBaseline: {alignItems: 'baseline'},
|
||||
justifyCenter: {justifyContent: 'center'},
|
||||
|
||||
// position
|
||||
absolute: {position: 'absolute'},
|
||||
|
||||
@@ -25,6 +25,7 @@ export const defaultTheme: Theme = {
|
||||
postCtrl: '#71768A',
|
||||
brandText: '#0066FF',
|
||||
emptyStateIcon: '#B6B6C9',
|
||||
borderLinkHover: '#cac1c1',
|
||||
},
|
||||
primary: {
|
||||
background: colors.blue3,
|
||||
@@ -310,6 +311,7 @@ export const darkTheme: Theme = {
|
||||
postCtrl: '#707489',
|
||||
brandText: '#0085ff',
|
||||
emptyStateIcon: colors.gray4,
|
||||
borderLinkHover: colors.gray5,
|
||||
},
|
||||
primary: {
|
||||
...defaultTheme.palette.primary,
|
||||
|
||||
@@ -5,6 +5,7 @@ import {AppLanguage} from '#/locale/languages'
|
||||
|
||||
test('sanitizeAppLanguageSetting', () => {
|
||||
expect(sanitizeAppLanguageSetting('en')).toBe(AppLanguage.en)
|
||||
expect(sanitizeAppLanguageSetting('pt-BR')).toBe(AppLanguage.pt_BR)
|
||||
expect(sanitizeAppLanguageSetting('hi')).toBe(AppLanguage.hi)
|
||||
expect(sanitizeAppLanguageSetting('foo')).toBe(AppLanguage.en)
|
||||
expect(sanitizeAppLanguageSetting('en,foo')).toBe(AppLanguage.en)
|
||||
|
||||
+14
-8
@@ -110,18 +110,24 @@ export function sanitizeAppLanguageSetting(appLanguage: string): AppLanguage {
|
||||
switch (lang) {
|
||||
case 'en':
|
||||
return AppLanguage.en
|
||||
case 'hi':
|
||||
return AppLanguage.hi
|
||||
case 'ja':
|
||||
return AppLanguage.ja
|
||||
case 'fr':
|
||||
return AppLanguage.fr
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// case 'de':
|
||||
// return AppLanguage.de
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// case 'es':
|
||||
// return AppLanguage.es
|
||||
case 'es':
|
||||
return AppLanguage.es
|
||||
case 'fr':
|
||||
return AppLanguage.fr
|
||||
case 'hi':
|
||||
return AppLanguage.hi
|
||||
case 'ja':
|
||||
return AppLanguage.ja
|
||||
case 'ko':
|
||||
return AppLanguage.ko
|
||||
case 'pt-BR':
|
||||
return AppLanguage.pt_BR
|
||||
case 'uk':
|
||||
return AppLanguage.uk
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
+30
-17
@@ -3,13 +3,15 @@ import {i18n} from '@lingui/core'
|
||||
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {messages as messagesEn} from '#/locale/locales/en/messages'
|
||||
import {messages as messagesHi} from '#/locale/locales/hi/messages'
|
||||
import {messages as messagesJa} from '#/locale/locales/ja/messages'
|
||||
import {messages as messagesFr} from '#/locale/locales/fr/messages'
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// import {messages as messagesDe} from '#/locale/locales/de/messages'
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// import {messages as messagesEs} from '#/locale/locales/es/messages'
|
||||
import {messages as messagesEs} from '#/locale/locales/es/messages'
|
||||
import {messages as messagesFr} from '#/locale/locales/fr/messages'
|
||||
import {messages as messagesHi} from '#/locale/locales/hi/messages'
|
||||
import {messages as messagesJa} from '#/locale/locales/ja/messages'
|
||||
import {messages as messagesKo} from '#/locale/locales/ko/messages'
|
||||
import {messages as messagesPt_BR} from '#/locale/locales/pt-BR/messages'
|
||||
import {messages as messagesUk} from '#/locale/locales/uk/messages'
|
||||
|
||||
import {sanitizeAppLanguageSetting} from '#/locale/helpers'
|
||||
import {AppLanguage} from '#/locale/languages'
|
||||
@@ -19,6 +21,19 @@ import {AppLanguage} from '#/locale/languages'
|
||||
*/
|
||||
export async function dynamicActivate(locale: AppLanguage) {
|
||||
switch (locale) {
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// case AppLanguage.de: {
|
||||
// i18n.loadAndActivate({locale, messages: messagesDe})
|
||||
// break
|
||||
// }
|
||||
case AppLanguage.es: {
|
||||
i18n.loadAndActivate({locale, messages: messagesEs})
|
||||
break
|
||||
}
|
||||
case AppLanguage.fr: {
|
||||
i18n.loadAndActivate({locale, messages: messagesFr})
|
||||
break
|
||||
}
|
||||
case AppLanguage.hi: {
|
||||
i18n.loadAndActivate({locale, messages: messagesHi})
|
||||
break
|
||||
@@ -27,20 +42,18 @@ export async function dynamicActivate(locale: AppLanguage) {
|
||||
i18n.loadAndActivate({locale, messages: messagesJa})
|
||||
break
|
||||
}
|
||||
case AppLanguage.fr: {
|
||||
i18n.loadAndActivate({locale, messages: messagesFr})
|
||||
case AppLanguage.ko: {
|
||||
i18n.loadAndActivate({locale, messages: messagesKo})
|
||||
break
|
||||
}
|
||||
case AppLanguage.pt_BR: {
|
||||
i18n.loadAndActivate({locale, messages: messagesPt_BR})
|
||||
break
|
||||
}
|
||||
case AppLanguage.uk: {
|
||||
i18n.loadAndActivate({locale, messages: messagesUk})
|
||||
break
|
||||
}
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// case AppLanguage.de: {
|
||||
// i18n.loadAndActivate({locale, messages: messagesDe})
|
||||
// break
|
||||
// }
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// case AppLanguage.es: {
|
||||
// i18n.loadAndActivate({locale, messages: messagesEs})
|
||||
// break
|
||||
// }
|
||||
default: {
|
||||
i18n.loadAndActivate({locale, messages: messagesEn})
|
||||
break
|
||||
|
||||
+23
-12
@@ -12,6 +12,19 @@ export async function dynamicActivate(locale: AppLanguage) {
|
||||
let mod: any
|
||||
|
||||
switch (locale) {
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// case AppLanguage.de: {
|
||||
// mod = await import(`./locales/de/messages`)
|
||||
// break
|
||||
// }
|
||||
case AppLanguage.es: {
|
||||
mod = await import(`./locales/es/messages`)
|
||||
break
|
||||
}
|
||||
case AppLanguage.fr: {
|
||||
mod = await import(`./locales/fr/messages`)
|
||||
break
|
||||
}
|
||||
case AppLanguage.hi: {
|
||||
mod = await import(`./locales/hi/messages`)
|
||||
break
|
||||
@@ -20,20 +33,18 @@ export async function dynamicActivate(locale: AppLanguage) {
|
||||
mod = await import(`./locales/ja/messages`)
|
||||
break
|
||||
}
|
||||
case AppLanguage.fr: {
|
||||
mod = await import(`./locales/fr/messages`)
|
||||
case AppLanguage.ko: {
|
||||
mod = await import(`./locales/ko/messages`)
|
||||
break
|
||||
}
|
||||
case AppLanguage.pt_BR: {
|
||||
mod = await import(`./locales/pt-BR/messages`)
|
||||
break
|
||||
}
|
||||
case AppLanguage.uk: {
|
||||
mod = await import(`./locales/uk/messages`)
|
||||
break
|
||||
}
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// case AppLanguage.de: {
|
||||
// mod = await import(`./locales/de/messages`)
|
||||
// break
|
||||
// }
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// case AppLanguage.es: {
|
||||
// mod = await import(`./locales/es/messages`)
|
||||
// break
|
||||
// }
|
||||
default: {
|
||||
mod = await import(`./locales/en/messages`)
|
||||
break
|
||||
|
||||
+14
-10
@@ -6,13 +6,15 @@ interface Language {
|
||||
|
||||
export enum AppLanguage {
|
||||
en = 'en',
|
||||
hi = 'hi',
|
||||
ja = 'ja',
|
||||
fr = 'fr',
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// de = 'de',
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// es = 'es',
|
||||
es = 'es',
|
||||
fr = 'fr',
|
||||
hi = 'hi',
|
||||
ja = 'ja',
|
||||
ko = 'ko',
|
||||
pt_BR = 'pt-BR',
|
||||
uk = 'uk',
|
||||
}
|
||||
|
||||
interface AppLanguageConfig {
|
||||
@@ -22,13 +24,15 @@ interface AppLanguageConfig {
|
||||
|
||||
export const APP_LANGUAGES: AppLanguageConfig[] = [
|
||||
{code2: AppLanguage.en, name: 'English'},
|
||||
{code2: AppLanguage.hi, name: 'हिंदी'},
|
||||
{code2: AppLanguage.ja, name: '日本語'},
|
||||
{code2: AppLanguage.fr, name: 'Français'},
|
||||
// DISABLED until this translation is fixed -prf
|
||||
// {code2: AppLanguage.de, name: 'Deutsch'},
|
||||
// DISABLED until this translation is more thoroughly reviewed -prf
|
||||
// {code2: AppLanguage.es, name: 'Español'},
|
||||
{code2: AppLanguage.es, name: 'Español'},
|
||||
{code2: AppLanguage.fr, name: 'Français'},
|
||||
{code2: AppLanguage.hi, name: 'हिंदी'},
|
||||
{code2: AppLanguage.ja, name: '日本語'},
|
||||
{code2: AppLanguage.ko, name: '한국어'},
|
||||
{code2: AppLanguage.pt_BR, name: 'Português (BR)'},
|
||||
{code2: AppLanguage.uk, name: 'Українська'},
|
||||
]
|
||||
|
||||
export const LANGUAGES: Language[] = [
|
||||
|
||||
@@ -68,7 +68,7 @@ msgstr "Eine neue Version der App ist verfügbar. Bitte aktualisieren Sie die Ap
|
||||
msgid "Accessibility"
|
||||
msgstr "Zugänglichkeit"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:159
|
||||
#: src/view/com/auth/login/LoginForm.tsx:163
|
||||
#: src/view/screens/Settings.tsx:286
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
@@ -98,6 +98,7 @@ msgstr "Konto hinzufügen"
|
||||
|
||||
#: src/view/com/composer/photos/Gallery.tsx:119
|
||||
#: src/view/com/composer/photos/Gallery.tsx:180
|
||||
#: src/view/com/modals/AltImage.tsx:93
|
||||
msgid "Add alt text"
|
||||
msgstr "Alt Text hinzufügen"
|
||||
|
||||
@@ -110,11 +111,11 @@ msgstr "Einzelheiten hinzufügen"
|
||||
msgid "Add details to report"
|
||||
msgstr "Einzelheiten zum Bericht hinzufügen"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:442
|
||||
#: src/view/com/composer/Composer.tsx:447
|
||||
msgid "Add link card"
|
||||
msgstr "Link Karte hinzufügen"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:445
|
||||
#: src/view/com/composer/Composer.tsx:450
|
||||
msgid "Add link card:"
|
||||
msgstr "Link Karte hinzufügen:"
|
||||
|
||||
@@ -135,7 +136,7 @@ msgstr "Zu meinen Feeds hinzufügen"
|
||||
msgid "Added to list"
|
||||
msgstr "Den Listen hinzufügen"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:164
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:170
|
||||
msgid "Adjust the number of likes a reply must have to be shown in your feed."
|
||||
msgstr "Passen Sie die Anzahl der Likes an, die eine Antwort haben muss, um in Ihrem Feed angezeigt zu werden."
|
||||
|
||||
@@ -143,7 +144,7 @@ msgstr "Passen Sie die Anzahl der Likes an, die eine Antwort haben muss, um in I
|
||||
msgid "Adult Content"
|
||||
msgstr "Inhalt für Erwachsene"
|
||||
|
||||
#: src/view/screens/Settings.tsx:569
|
||||
#: src/view/screens/Settings.tsx:602
|
||||
msgid "Advanced"
|
||||
msgstr "Fortgeschrittene"
|
||||
|
||||
@@ -176,7 +177,7 @@ msgstr "und"
|
||||
msgid "App Language"
|
||||
msgstr "App Sprache"
|
||||
|
||||
#: src/view/screens/Settings.tsx:589
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
msgid "App passwords"
|
||||
msgstr "App-Passwörter"
|
||||
|
||||
@@ -212,7 +213,7 @@ msgstr "Aussehen"
|
||||
msgid "Are you sure you want to delete the app password \"{name}\"?"
|
||||
msgstr "Sind Sie sicher, dass Sie das App-Passwort \"{name}\" löschen möchten?"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:142
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr "Sind Sie sicher, dass Sie diesen Entwurf verwerfen möchten?"
|
||||
|
||||
@@ -231,7 +232,7 @@ msgstr "Künstlerische oder nicht-erotische Nacktheit."
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:141
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:151
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:166
|
||||
#: src/view/com/auth/login/LoginForm.tsx:250
|
||||
#: src/view/com/auth/login/LoginForm.tsx:254
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:148
|
||||
#: src/view/com/modals/report/InputIssueDetails.tsx:46
|
||||
#: src/view/com/post-thread/PostThread.tsx:388
|
||||
@@ -327,7 +328,7 @@ msgstr "Bluesky wird dein Profil und deine Beiträge nicht für abgemeldete Benu
|
||||
msgid "Bluesky.Social"
|
||||
msgstr "Bluesky.Social"
|
||||
|
||||
#: src/view/screens/Settings.tsx:718
|
||||
#: src/view/screens/Settings.tsx:751
|
||||
msgid "Build version {0} {1}"
|
||||
msgstr "Version bauen {0} {1}"
|
||||
|
||||
@@ -345,9 +346,8 @@ msgstr "Kamera"
|
||||
msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long."
|
||||
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/view/com/composer/Composer.tsx:289
|
||||
#: src/view/com/composer/Composer.tsx:292
|
||||
#: src/view/com/modals/AltImage.tsx:128
|
||||
#: src/view/com/composer/Composer.tsx:294
|
||||
#: src/view/com/composer/Composer.tsx:297
|
||||
#: src/view/com/modals/ChangeEmail.tsx:218
|
||||
#: src/view/com/modals/ChangeEmail.tsx:220
|
||||
#: src/view/com/modals/Confirm.tsx:88
|
||||
@@ -371,8 +371,8 @@ msgid "Cancel account deletion"
|
||||
msgstr "Kontolöschung abbrechen"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:123
|
||||
msgid "Cancel add image alt text"
|
||||
msgstr "Abbrechen Bild-Alt-Text hinzufügen"
|
||||
#~ msgid "Cancel add image alt text"
|
||||
#~ msgstr "Abbrechen Bild-Alt-Text hinzufügen"
|
||||
|
||||
#: src/view/com/modals/ChangeHandle.tsx:149
|
||||
msgid "Cancel change handle"
|
||||
@@ -403,8 +403,8 @@ msgstr "Anmeldung zur Warteliste abbrechen"
|
||||
msgid "Change"
|
||||
msgstr "Ändern"
|
||||
|
||||
#: src/view/screens/Settings.tsx:601
|
||||
#: src/view/screens/Settings.tsx:610
|
||||
#: src/view/screens/Settings.tsx:634
|
||||
#: src/view/screens/Settings.tsx:643
|
||||
msgid "Change handle"
|
||||
msgstr "Änderungsgriff andern"
|
||||
|
||||
@@ -448,19 +448,19 @@ msgstr "Wählen Sie die Algorithmen, die Ihr Erlebnis mit benutzerdefinierten Fe
|
||||
msgid "Choose your password"
|
||||
msgstr "Wählen Sie Ihr Passwort"
|
||||
|
||||
#: src/view/screens/Settings.tsx:694
|
||||
#: src/view/screens/Settings.tsx:727
|
||||
msgid "Clear all legacy storage data"
|
||||
msgstr "Alle alten Speicherdaten löschen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:696
|
||||
#: src/view/screens/Settings.tsx:729
|
||||
msgid "Clear all legacy storage data (restart after this)"
|
||||
msgstr "Alle alten Speicherdaten löschen (danach neu starten)"
|
||||
|
||||
#: src/view/screens/Settings.tsx:706
|
||||
#: src/view/screens/Settings.tsx:739
|
||||
msgid "Clear all storage data"
|
||||
msgstr "Alle alten Speicherdaten löschen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:708
|
||||
#: src/view/screens/Settings.tsx:741
|
||||
msgid "Clear all storage data (restart after this)"
|
||||
msgstr "Alle alten Speicherdaten löschen (danach neu starten)"
|
||||
|
||||
@@ -501,8 +501,8 @@ msgstr "Antwort zusammenstellen"
|
||||
#: src/view/com/modals/Confirm.tsx:75
|
||||
#: src/view/com/modals/SelfLabel.tsx:154
|
||||
#: src/view/com/modals/VerifyEmail.tsx:225
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:299
|
||||
#: src/view/screens/PreferencesThreads.tsx:153
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:305
|
||||
#: src/view/screens/PreferencesThreads.tsx:159
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätigen"
|
||||
|
||||
@@ -526,7 +526,7 @@ msgid "Confirmation code"
|
||||
msgstr "Bestätigungscode"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:269
|
||||
#: src/view/com/auth/login/LoginForm.tsx:273
|
||||
msgid "Connecting..."
|
||||
msgstr "Verbinden..."
|
||||
|
||||
@@ -616,11 +616,15 @@ msgstr "Erstellt {0}"
|
||||
msgid "Custom domain"
|
||||
msgstr "Benutzerdefinierter Bereich"
|
||||
|
||||
#: src/view/screens/Settings.tsx:615
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:55
|
||||
msgid "Customize media from external sites."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:648
|
||||
msgid "Danger Zone"
|
||||
msgstr "Gefahrenzone"
|
||||
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
#: src/view/screens/Settings.tsx:655
|
||||
msgid "Delete account"
|
||||
msgstr "Konto löschen"
|
||||
|
||||
@@ -642,7 +646,7 @@ msgstr "Liste löschen"
|
||||
msgid "Delete my account"
|
||||
msgstr "Mein Konto löschen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:632
|
||||
#: src/view/screens/Settings.tsx:665
|
||||
msgid "Delete my account…"
|
||||
msgstr "Mein Konto löschen..."
|
||||
|
||||
@@ -669,19 +673,19 @@ msgstr "Beschreibung"
|
||||
msgid "Dev Server"
|
||||
msgstr "Entwicklungs-Server"
|
||||
|
||||
#: src/view/screens/Settings.tsx:637
|
||||
#: src/view/screens/Settings.tsx:670
|
||||
msgid "Developer Tools"
|
||||
msgstr "Werkzeuge für Entwickler"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:210
|
||||
#: src/view/com/composer/Composer.tsx:211
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
#: src/view/com/composer/Composer.tsx:144
|
||||
msgid "Discard"
|
||||
msgstr "Verwerfen"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:137
|
||||
#: src/view/com/composer/Composer.tsx:138
|
||||
msgid "Discard draft"
|
||||
msgstr "Verwerfen"
|
||||
|
||||
@@ -706,6 +710,7 @@ msgid "Domain verified!"
|
||||
msgstr "Domain geprüft!"
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:88
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:96
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:152
|
||||
@@ -715,8 +720,8 @@ msgstr "Domain geprüft!"
|
||||
#: src/view/com/modals/Threadgate.tsx:129
|
||||
#: src/view/com/modals/Threadgate.tsx:132
|
||||
#: src/view/com/modals/UserAddRemoveLists.tsx:79
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:302
|
||||
#: src/view/screens/PreferencesThreads.tsx:156
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:308
|
||||
#: src/view/screens/PreferencesThreads.tsx:162
|
||||
msgid "Done"
|
||||
msgstr "Erledigt"
|
||||
|
||||
@@ -777,7 +782,15 @@ msgstr "Email aktualiziert"
|
||||
msgid "Email:"
|
||||
msgstr "E-Mail:"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:138
|
||||
#: src/view/com/modals/EmbedConsent.tsx:113
|
||||
msgid "Enable {0} only"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:97
|
||||
msgid "Enable External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:144
|
||||
msgid "Enable this setting to only see replies between people you follow."
|
||||
msgstr "Aktivieren Sie diese Einstellung, um nur Antworten zwischen Personen zu sehen, denen Sie folgen."
|
||||
|
||||
@@ -821,6 +834,20 @@ msgstr "Alle"
|
||||
msgid "Expand alt text"
|
||||
msgstr "Alt-Text erweitern"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:64
|
||||
msgid "External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:75
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:66
|
||||
msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:52
|
||||
#: src/view/screens/Settings.tsx:595
|
||||
msgid "External Media Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141
|
||||
msgid "Failed to load recommended feeds"
|
||||
@@ -868,7 +895,7 @@ msgstr "Benutzer mit der Suchfunktion auf der rechten Seite finden"
|
||||
msgid "Finding similar accounts..."
|
||||
msgstr "Suche nach ähnlichen Konten..."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:102
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:108
|
||||
msgid "Fine-tune the content you see on your home screen."
|
||||
msgstr "Optimieren Sie die Inhalte, die Sie auf Ihrem Startbildschirm sehen."
|
||||
|
||||
@@ -888,7 +915,7 @@ msgstr "Folgen Sie einigen Nutzern, um loszulegen. Wir können Ihnen weitere Nut
|
||||
msgid "Followed users"
|
||||
msgstr "Verfolgte Benutzer"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:145
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:151
|
||||
msgid "Followed users only"
|
||||
msgstr "Nur verfolgte Benutzer"
|
||||
|
||||
@@ -917,11 +944,11 @@ msgstr "Aus Sicherheitsgründen müssen wir Ihnen einen Bestätigungscode an Ihr
|
||||
msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one."
|
||||
msgstr "Aus Sicherheitsgründen können Sie es nicht mehr einsehen. Wenn Sie dieses Passwort verlieren, müssen Sie ein neues generieren."
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:232
|
||||
#: src/view/com/auth/login/LoginForm.tsx:236
|
||||
msgid "Forgot"
|
||||
msgstr "Vergessen"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:229
|
||||
#: src/view/com/auth/login/LoginForm.tsx:233
|
||||
msgid "Forgot password"
|
||||
msgstr "Passwort vergessen"
|
||||
|
||||
@@ -953,7 +980,7 @@ msgid "Go Back"
|
||||
msgstr "Zurückgehen"
|
||||
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:181
|
||||
#: src/view/com/auth/login/LoginForm.tsx:279
|
||||
#: src/view/com/auth/login/LoginForm.tsx:283
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:163
|
||||
msgid "Go to next"
|
||||
msgstr "Weiter zum nächsten"
|
||||
@@ -1016,7 +1043,7 @@ msgid "Home"
|
||||
msgstr "Startseite"
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:96
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:95
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:101
|
||||
#: src/view/screens/Settings.tsx:481
|
||||
msgid "Home Feed Preferences"
|
||||
msgstr "Startseite Feed-Einstellungen"
|
||||
@@ -1051,7 +1078,7 @@ msgstr "Bild-Alt-Text"
|
||||
msgid "Image options"
|
||||
msgstr "Bild-Optionen"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:113
|
||||
#: src/view/com/auth/login/LoginForm.tsx:115
|
||||
msgid "Invalid username or password"
|
||||
msgstr "Ungültiger Benutzername oder Passwort"
|
||||
|
||||
@@ -1256,6 +1283,10 @@ msgstr "Mehr Feeds "
|
||||
msgid "More options"
|
||||
msgstr "Mehr Optionen"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:82
|
||||
msgid "Most-liked replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/profile/ProfileHeader.tsx:370
|
||||
msgid "Mute Account"
|
||||
msgstr "Stummes Konto"
|
||||
@@ -1313,6 +1344,11 @@ msgstr "Meine gespeicherte Feeds "
|
||||
msgid "Name"
|
||||
msgstr "Namen"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:107
|
||||
#: src/view/com/modals/EmbedConsent.tsx:123
|
||||
msgid "Never load embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72
|
||||
msgid "Never lose access to your followers and data."
|
||||
msgstr "Verlieren Sie nie den Zugriff auf Ihre Follower und Daten."
|
||||
@@ -1336,10 +1372,14 @@ msgstr "Neuer Posten "
|
||||
msgid "New Post"
|
||||
msgstr "Neuer Posten "
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:79
|
||||
msgid "Newest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:154
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:174
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:184
|
||||
#: src/view/com/auth/login/LoginForm.tsx:282
|
||||
#: src/view/com/auth/login/LoginForm.tsx:286
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:156
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:166
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79
|
||||
@@ -1350,10 +1390,12 @@ msgstr "Nächster"
|
||||
msgid "Next image"
|
||||
msgstr "Nächstes Bild "
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:191
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:226
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:263
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:197
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:232
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:269
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
@@ -1378,6 +1420,10 @@ msgstr "Keine Ergebnisse gefunden für \"{query}\""
|
||||
msgid "No results found for {query}"
|
||||
msgstr "Keine Ergebnisse gefunden für {query}"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:129
|
||||
msgid "No thanks"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:82
|
||||
msgid "Nobody"
|
||||
msgstr "Niemand"
|
||||
@@ -1407,7 +1453,11 @@ msgstr "Ach nein!"
|
||||
msgid "Okay"
|
||||
msgstr "Okay"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:358
|
||||
#: src/view/screens/PreferencesThreads.tsx:78
|
||||
msgid "Oldest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:363
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr "Bei einem oder mehreren Bildern fehlt der Alt-Text."
|
||||
|
||||
@@ -1415,6 +1465,11 @@ msgstr "Bei einem oder mehreren Bildern fehlt der Alt-Text."
|
||||
msgid "Only {0} can reply."
|
||||
msgstr "Nur {0} kann antworten."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
#: src/view/com/composer/Composer.tsx:469
|
||||
msgid "Open emoji picker"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:76
|
||||
msgid "Open navigation"
|
||||
msgstr "Offene Navigation"
|
||||
@@ -1423,6 +1478,10 @@ msgstr "Offene Navigation"
|
||||
msgid "Opens configurable language settings"
|
||||
msgstr "Öffnet die konfigurierbaren Spracheinstellungen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:587
|
||||
msgid "Opens external embeds settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:156
|
||||
#: src/view/shell/Drawer.tsx:641
|
||||
msgid "Opens list of invite codes"
|
||||
@@ -1440,7 +1499,7 @@ msgstr "Öffnet die Moderationseinstellungen"
|
||||
msgid "Opens screen with all saved feeds"
|
||||
msgstr "Öffnet den Bildschirm mit allen gespeicherten Feeds"
|
||||
|
||||
#: src/view/screens/Settings.tsx:581
|
||||
#: src/view/screens/Settings.tsx:614
|
||||
msgid "Opens the app password settings page"
|
||||
msgstr "Öffnet die Einstellungsseite für das App-Passwort"
|
||||
|
||||
@@ -1448,11 +1507,11 @@ msgstr "Öffnet die Einstellungsseite für das App-Passwort"
|
||||
msgid "Opens the home feed preferences"
|
||||
msgstr "Öffnet die Homefeed-Einstellungen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:664
|
||||
#: src/view/screens/Settings.tsx:697
|
||||
msgid "Opens the storybook page"
|
||||
msgstr "Öffnet die Märchenbuchseite"
|
||||
|
||||
#: src/view/screens/Settings.tsx:644
|
||||
#: src/view/screens/Settings.tsx:677
|
||||
msgid "Opens the system log page"
|
||||
msgstr "Öffnet die Systemprotokollseite"
|
||||
|
||||
@@ -1483,7 +1542,7 @@ msgstr "Seite nicht gefunden"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:122
|
||||
#: src/view/com/auth/create/Step2.tsx:132
|
||||
#: src/view/com/auth/login/LoginForm.tsx:217
|
||||
#: src/view/com/auth/login/LoginForm.tsx:221
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:130
|
||||
#: src/view/com/modals/DeleteAccount.tsx:191
|
||||
msgid "Password"
|
||||
@@ -1505,6 +1564,19 @@ msgstr "Bilder, die für Erwachsene gedacht sind."
|
||||
msgid "Pinned Feeds"
|
||||
msgstr "Angepinnte Feeds"
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111
|
||||
msgid "Play {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55
|
||||
msgid "Play Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110
|
||||
msgid "Plays the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:116
|
||||
msgid "Please choose your handle."
|
||||
msgstr "Bitte wählen Sie Ihren Handgriff."
|
||||
@@ -1539,11 +1611,11 @@ msgstr ""
|
||||
#~ msgid "Please tell us why you think this decision was incorrect."
|
||||
#~ msgstr "Bitte teilen Sie uns mit, warum diese Entscheidung Ihrer Meinung nach falsch war."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:214
|
||||
#: src/view/com/composer/Composer.tsx:215
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:341
|
||||
#: src/view/com/composer/Composer.tsx:346
|
||||
#: src/view/com/post-thread/PostThread.tsx:225
|
||||
#: src/view/screens/PostThread.tsx:80
|
||||
msgid "Post"
|
||||
@@ -1581,16 +1653,17 @@ msgstr "Vorheriges Bild"
|
||||
msgid "Primary Language"
|
||||
msgstr "Primäre Sprache"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:91
|
||||
#: src/view/screens/PreferencesThreads.tsx:97
|
||||
msgid "Prioritize Your Follows"
|
||||
msgstr "Priorisieren Sie Ihre Anhängerschaft"
|
||||
|
||||
#: src/view/screens/Settings.tsx:570
|
||||
#: src/view/shell/desktop/RightNav.tsx:84
|
||||
msgid "Privacy"
|
||||
msgstr "Privatsphäre"
|
||||
|
||||
#: src/view/screens/PrivacyPolicy.tsx:29
|
||||
#: src/view/screens/Settings.tsx:750
|
||||
#: src/view/screens/Settings.tsx:783
|
||||
#: src/view/shell/Drawer.tsx:262
|
||||
msgid "Privacy Policy"
|
||||
msgstr "Datenschutzbestimmungen"
|
||||
@@ -1607,7 +1680,7 @@ msgstr "Verarbeitung..."
|
||||
msgid "Profile"
|
||||
msgstr "Profile"
|
||||
|
||||
#: src/view/screens/Settings.tsx:808
|
||||
#: src/view/screens/Settings.tsx:841
|
||||
msgid "Protect your account by verifying your email."
|
||||
msgstr "Schützen Sie Ihr Konto, indem Sie Ihre E-Mail verifizieren."
|
||||
|
||||
@@ -1628,6 +1701,10 @@ msgstr "Angebotsposten"
|
||||
msgid "Quote Post"
|
||||
msgstr "Angebotsposten"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:86
|
||||
msgid "Random (aka \"Poster's Roulette\")"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EditImage.tsx:236
|
||||
msgid "Ratios"
|
||||
msgstr "Verhältnisse"
|
||||
@@ -1695,7 +1772,7 @@ msgstr "Antworten"
|
||||
msgid "Replies to this thread are disabled"
|
||||
msgstr "Antworten auf diesen Thread sind deaktiviert"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:135
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:141
|
||||
msgid "Reply Filters"
|
||||
msgstr "Antwort-Filter"
|
||||
|
||||
@@ -1738,6 +1815,10 @@ msgstr "Nachgetragen von"
|
||||
msgid "Request Change"
|
||||
msgstr "Änderung beantragen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:422
|
||||
msgid "Require alt text before posting"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:68
|
||||
msgid "Required for this provider"
|
||||
msgstr "Für diesen Anbieter erforderlich"
|
||||
@@ -1746,7 +1827,7 @@ msgstr "Für diesen Anbieter erforderlich"
|
||||
msgid "Reset code"
|
||||
msgstr "Code zurücksetzen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:686
|
||||
#: src/view/screens/Settings.tsx:719
|
||||
msgid "Reset onboarding state"
|
||||
msgstr "Onboarding-Status zurücksetzen"
|
||||
|
||||
@@ -1754,28 +1835,27 @@ msgstr "Onboarding-Status zurücksetzen"
|
||||
msgid "Reset password"
|
||||
msgstr "Passwort zurücksetzen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:676
|
||||
#: src/view/screens/Settings.tsx:709
|
||||
msgid "Reset preferences state"
|
||||
msgstr "Einstellungen zurücksetzen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:684
|
||||
#: src/view/screens/Settings.tsx:717
|
||||
msgid "Resets the onboarding state"
|
||||
msgstr "Onboarding-Status zurücksetzen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:674
|
||||
#: src/view/screens/Settings.tsx:707
|
||||
msgid "Resets the preferences state"
|
||||
msgstr "Setzt den Zustand der Einstellungen zurück"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:163
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:167
|
||||
#: src/view/com/auth/login/LoginForm.tsx:259
|
||||
#: src/view/com/auth/login/LoginForm.tsx:262
|
||||
#: src/view/com/auth/login/LoginForm.tsx:263
|
||||
#: src/view/com/auth/login/LoginForm.tsx:266
|
||||
#: src/view/com/util/error/ErrorMessage.tsx:55
|
||||
#: src/view/com/util/error/ErrorScreen.tsx:65
|
||||
msgid "Retry"
|
||||
msgstr "Wiederholung"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:94
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:97
|
||||
#: src/view/com/modals/ChangeHandle.tsx:173
|
||||
@@ -1839,7 +1919,7 @@ msgstr "Wählen Sie Bluesky Social"
|
||||
msgid "Select from an existing account"
|
||||
msgstr "Aus einem bestehenden Konto auswählen"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:143
|
||||
#: src/view/com/auth/login/LoginForm.tsx:147
|
||||
msgid "Select service"
|
||||
msgstr "Dienst auswählen"
|
||||
|
||||
@@ -1880,23 +1960,23 @@ msgstr "Bericht senden"
|
||||
msgid "Set new password"
|
||||
msgstr "Neues Passwort festlegen"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:216
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:222
|
||||
msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible."
|
||||
msgstr "Setzen Sie diese Einstellung auf \"Nein\", um alle zitierten Beiträge aus Ihrem Feed auszublenden. Neu eingestellte Beiträge sind weiterhin sichtbar."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:113
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:119
|
||||
msgid "Set this setting to \"No\" to hide all replies from your feed."
|
||||
msgstr "Setzen Sie diese Einstellung auf \"Nein\", um alle Antworten aus Ihrem Feed auszublenden."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:182
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:188
|
||||
msgid "Set this setting to \"No\" to hide all reposts from your feed."
|
||||
msgstr "Setzen Sie diese Einstellung auf \"Nein\", um alle wieder geposteten Beiträge aus Ihrem Feed auszublenden."
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:116
|
||||
#: src/view/screens/PreferencesThreads.tsx:122
|
||||
msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature."
|
||||
msgstr "Setzen Sie diese Einstellung auf \"Ja\", um Antworten in einer Thread-Ansicht anzuzeigen. Dies ist eine experimentelle Funktion."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:252
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:258
|
||||
msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature."
|
||||
msgstr "Setzen Sie diese Einstellung auf \"Ja\", um Beispiele für Ihre gespeicherten Feeds in Ihrem folgenden Feed anzuzeigen. Dies ist eine experimentelle Funktion."
|
||||
|
||||
@@ -1930,23 +2010,27 @@ msgstr "Zeigen"
|
||||
msgid "Show anyway"
|
||||
msgstr "Trotzdem anzeigen"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:249
|
||||
#: src/view/com/modals/EmbedConsent.tsx:87
|
||||
msgid "Show embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:255
|
||||
msgid "Show Posts from My Feeds"
|
||||
msgstr "Beiträge von My Feeds anzeigen"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:213
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:219
|
||||
msgid "Show Quote Posts"
|
||||
msgstr "Angebotsposten zeigen"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:110
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:116
|
||||
msgid "Show Replies"
|
||||
msgstr "Antworten zeigen"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:94
|
||||
#: src/view/screens/PreferencesThreads.tsx:100
|
||||
msgid "Show replies by people you follow before all other replies."
|
||||
msgstr "Antworten von Personen, denen Sie folgen, vor allen anderen Antworten anzeigen."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:179
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:185
|
||||
msgid "Show Reposts"
|
||||
msgstr "Wiederholungen anzeigen"
|
||||
|
||||
@@ -1983,7 +2067,7 @@ msgstr "Eintragen als {0}"
|
||||
msgid "Sign in as..."
|
||||
msgstr "Eintragen als..."
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:130
|
||||
#: src/view/com/auth/login/LoginForm.tsx:134
|
||||
msgid "Sign into"
|
||||
msgstr "Anmelden"
|
||||
|
||||
@@ -2037,11 +2121,11 @@ msgstr "Platz"
|
||||
msgid "Staging"
|
||||
msgstr "Aufführung"
|
||||
|
||||
#: src/view/screens/Settings.tsx:730
|
||||
#: src/view/screens/Settings.tsx:763
|
||||
msgid "Status page"
|
||||
msgstr "Status-Seite"
|
||||
|
||||
#: src/view/screens/Settings.tsx:666
|
||||
#: src/view/screens/Settings.tsx:699
|
||||
msgid "Storybook"
|
||||
msgstr "Märchenbuch"
|
||||
|
||||
@@ -2070,7 +2154,7 @@ msgstr "Unterstützung"
|
||||
msgid "Switch Account"
|
||||
msgstr "Konto wechseln"
|
||||
|
||||
#: src/view/screens/Settings.tsx:646
|
||||
#: src/view/screens/Settings.tsx:679
|
||||
msgid "System log"
|
||||
msgstr "System-Protokoll"
|
||||
|
||||
@@ -2082,7 +2166,7 @@ msgstr "Groß"
|
||||
msgid "Terms"
|
||||
msgstr "Bedingungen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:744
|
||||
#: src/view/screens/Settings.tsx:777
|
||||
#: src/view/screens/TermsOfService.tsx:29
|
||||
#: src/view/shell/Drawer.tsx:256
|
||||
msgid "Terms of Service"
|
||||
@@ -2137,6 +2221,10 @@ msgstr "Diese {screenDescription} wurde markiert:"
|
||||
msgid "This account has requested that users sign in to view their profile."
|
||||
msgstr "Dieses Konto hat die Benutzer aufgefordert, sich anzumelden, um ihr Profil zu sehen."
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:68
|
||||
msgid "This content is hosted by {0}. Do you want to enable external media?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/posts/FeedErrorMessage.tsx:107
|
||||
msgid "This content is not viewable without a Bluesky account."
|
||||
msgstr "Dieser Inhalt kann ohne Bluesky-Konto nicht angezeigt werden."
|
||||
@@ -2178,7 +2266,7 @@ msgstr ""
|
||||
msgid "Thread Preferences"
|
||||
msgstr "Einstellungen zum Thema"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:113
|
||||
#: src/view/screens/PreferencesThreads.tsx:119
|
||||
msgid "Threaded Mode"
|
||||
msgstr "Gewindemodus"
|
||||
|
||||
@@ -2210,7 +2298,7 @@ msgstr "Stummschaltliste aufheben"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:65
|
||||
#: src/view/com/auth/login/Login.tsx:76
|
||||
#: src/view/com/auth/login/LoginForm.tsx:117
|
||||
#: src/view/com/auth/login/LoginForm.tsx:120
|
||||
msgid "Unable to contact your service. Please check your Internet connection."
|
||||
msgstr "Sie können Ihren Dienst nicht kontaktieren. Bitte überprüfen Sie Ihre Internetverbindung."
|
||||
|
||||
@@ -2228,7 +2316,7 @@ msgstr "Konto freischalten"
|
||||
msgid "Undo repost"
|
||||
msgstr "Umbuchung rückgängig machen"
|
||||
|
||||
#: src/view/com/auth/create/state.ts:210
|
||||
#: src/view/com/auth/create/state.ts:216
|
||||
msgid "Unfortunately, you do not meet the requirements to create an account."
|
||||
msgstr "Leider erfüllen Sie nicht die Voraussetzungen, um ein Konto zu erstellen."
|
||||
|
||||
@@ -2284,8 +2372,8 @@ msgstr "Benutzerhandgriff"
|
||||
msgid "User Lists"
|
||||
msgstr "Benutzer Liste"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:170
|
||||
#: src/view/com/auth/login/LoginForm.tsx:188
|
||||
#: src/view/com/auth/login/LoginForm.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:192
|
||||
msgid "Username or email address"
|
||||
msgstr "Benutzername oder E-Mail Adresse"
|
||||
|
||||
@@ -2301,15 +2389,15 @@ msgstr "Benutzer gefolgt von <0/>"
|
||||
msgid "Users in \"{0}\""
|
||||
msgstr "Benutzer in \"{0}\""
|
||||
|
||||
#: src/view/screens/Settings.tsx:769
|
||||
#: src/view/screens/Settings.tsx:802
|
||||
msgid "Verify email"
|
||||
msgstr "E-Mail überprüfen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:794
|
||||
#: src/view/screens/Settings.tsx:827
|
||||
msgid "Verify my email"
|
||||
msgstr "E-Mail überprüfen"
|
||||
|
||||
#: src/view/screens/Settings.tsx:803
|
||||
#: src/view/screens/Settings.tsx:836
|
||||
msgid "Verify My Email"
|
||||
msgstr "E-Mail überprüfen"
|
||||
|
||||
@@ -2375,7 +2463,7 @@ msgstr "Wer kann antworten."
|
||||
msgid "Wide"
|
||||
msgstr "Breit"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:413
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
msgid "Write post"
|
||||
msgstr "Posten schreiben"
|
||||
|
||||
@@ -2383,10 +2471,12 @@ msgstr "Posten schreiben"
|
||||
msgid "Write your reply"
|
||||
msgstr "Schreiben Sie Ihre Antwort"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:192
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:227
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:262
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:198
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:233
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:268
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ msgstr ""
|
||||
msgid "Accessibility"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:159
|
||||
#: src/view/com/auth/login/LoginForm.tsx:163
|
||||
#: src/view/screens/Settings.tsx:286
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
@@ -118,6 +118,7 @@ msgstr ""
|
||||
|
||||
#: src/view/com/composer/photos/Gallery.tsx:119
|
||||
#: src/view/com/composer/photos/Gallery.tsx:180
|
||||
#: src/view/com/modals/AltImage.tsx:93
|
||||
msgid "Add alt text"
|
||||
msgstr ""
|
||||
|
||||
@@ -130,11 +131,11 @@ msgstr ""
|
||||
msgid "Add details to report"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:442
|
||||
#: src/view/com/composer/Composer.tsx:447
|
||||
msgid "Add link card"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:445
|
||||
#: src/view/com/composer/Composer.tsx:450
|
||||
msgid "Add link card:"
|
||||
msgstr ""
|
||||
|
||||
@@ -155,7 +156,7 @@ msgstr ""
|
||||
msgid "Added to list"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:164
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:170
|
||||
msgid "Adjust the number of likes a reply must have to be shown in your feed."
|
||||
msgstr ""
|
||||
|
||||
@@ -163,7 +164,7 @@ msgstr ""
|
||||
msgid "Adult Content"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:569
|
||||
#: src/view/screens/Settings.tsx:602
|
||||
msgid "Advanced"
|
||||
msgstr ""
|
||||
|
||||
@@ -196,7 +197,7 @@ msgstr ""
|
||||
msgid "App Language"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:589
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
msgid "App passwords"
|
||||
msgstr ""
|
||||
|
||||
@@ -236,7 +237,7 @@ msgstr ""
|
||||
msgid "Are you sure you want to delete the app password \"{name}\"?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:142
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr ""
|
||||
|
||||
@@ -259,7 +260,7 @@ msgstr ""
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:141
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:151
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:166
|
||||
#: src/view/com/auth/login/LoginForm.tsx:250
|
||||
#: src/view/com/auth/login/LoginForm.tsx:254
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:148
|
||||
#: src/view/com/modals/report/InputIssueDetails.tsx:46
|
||||
#: src/view/com/post-thread/PostThread.tsx:388
|
||||
@@ -355,7 +356,7 @@ msgstr ""
|
||||
msgid "Bluesky.Social"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:718
|
||||
#: src/view/screens/Settings.tsx:751
|
||||
msgid "Build version {0} {1}"
|
||||
msgstr ""
|
||||
|
||||
@@ -373,9 +374,8 @@ msgstr ""
|
||||
msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:289
|
||||
#: src/view/com/composer/Composer.tsx:292
|
||||
#: src/view/com/modals/AltImage.tsx:128
|
||||
#: src/view/com/composer/Composer.tsx:294
|
||||
#: src/view/com/composer/Composer.tsx:297
|
||||
#: src/view/com/modals/ChangeEmail.tsx:218
|
||||
#: src/view/com/modals/ChangeEmail.tsx:220
|
||||
#: src/view/com/modals/Confirm.tsx:88
|
||||
@@ -399,8 +399,8 @@ msgid "Cancel account deletion"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:123
|
||||
msgid "Cancel add image alt text"
|
||||
msgstr ""
|
||||
#~ msgid "Cancel add image alt text"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/modals/ChangeHandle.tsx:149
|
||||
msgid "Cancel change handle"
|
||||
@@ -431,8 +431,8 @@ msgstr ""
|
||||
msgid "Change"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:601
|
||||
#: src/view/screens/Settings.tsx:610
|
||||
#: src/view/screens/Settings.tsx:634
|
||||
#: src/view/screens/Settings.tsx:643
|
||||
msgid "Change handle"
|
||||
msgstr ""
|
||||
|
||||
@@ -480,19 +480,19 @@ msgstr ""
|
||||
msgid "Choose your password"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:694
|
||||
#: src/view/screens/Settings.tsx:727
|
||||
msgid "Clear all legacy storage data"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:696
|
||||
#: src/view/screens/Settings.tsx:729
|
||||
msgid "Clear all legacy storage data (restart after this)"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:706
|
||||
#: src/view/screens/Settings.tsx:739
|
||||
msgid "Clear all storage data"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:708
|
||||
#: src/view/screens/Settings.tsx:741
|
||||
msgid "Clear all storage data (restart after this)"
|
||||
msgstr ""
|
||||
|
||||
@@ -533,8 +533,8 @@ msgstr ""
|
||||
#: src/view/com/modals/Confirm.tsx:75
|
||||
#: src/view/com/modals/SelfLabel.tsx:154
|
||||
#: src/view/com/modals/VerifyEmail.tsx:225
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:299
|
||||
#: src/view/screens/PreferencesThreads.tsx:153
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:305
|
||||
#: src/view/screens/PreferencesThreads.tsx:159
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
@@ -558,7 +558,7 @@ msgid "Confirmation code"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:269
|
||||
#: src/view/com/auth/login/LoginForm.tsx:273
|
||||
msgid "Connecting..."
|
||||
msgstr ""
|
||||
|
||||
@@ -648,7 +648,11 @@ msgstr ""
|
||||
msgid "Custom domain"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:615
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:55
|
||||
msgid "Customize media from external sites."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:648
|
||||
msgid "Danger Zone"
|
||||
msgstr ""
|
||||
|
||||
@@ -656,7 +660,7 @@ msgstr ""
|
||||
#~ msgid "Dark"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
#: src/view/screens/Settings.tsx:655
|
||||
msgid "Delete account"
|
||||
msgstr ""
|
||||
|
||||
@@ -678,7 +682,7 @@ msgstr ""
|
||||
msgid "Delete my account"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:632
|
||||
#: src/view/screens/Settings.tsx:665
|
||||
msgid "Delete my account…"
|
||||
msgstr ""
|
||||
|
||||
@@ -705,19 +709,19 @@ msgstr ""
|
||||
msgid "Dev Server"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:637
|
||||
#: src/view/screens/Settings.tsx:670
|
||||
msgid "Developer Tools"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:210
|
||||
#: src/view/com/composer/Composer.tsx:211
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
#: src/view/com/composer/Composer.tsx:144
|
||||
msgid "Discard"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:137
|
||||
#: src/view/com/composer/Composer.tsx:138
|
||||
msgid "Discard draft"
|
||||
msgstr ""
|
||||
|
||||
@@ -742,6 +746,7 @@ msgid "Domain verified!"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:88
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:96
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:152
|
||||
@@ -751,8 +756,8 @@ msgstr ""
|
||||
#: src/view/com/modals/Threadgate.tsx:129
|
||||
#: src/view/com/modals/Threadgate.tsx:132
|
||||
#: src/view/com/modals/UserAddRemoveLists.tsx:79
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:302
|
||||
#: src/view/screens/PreferencesThreads.tsx:156
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:308
|
||||
#: src/view/screens/PreferencesThreads.tsx:162
|
||||
msgid "Done"
|
||||
msgstr ""
|
||||
|
||||
@@ -813,7 +818,15 @@ msgstr ""
|
||||
msgid "Email:"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:138
|
||||
#: src/view/com/modals/EmbedConsent.tsx:113
|
||||
msgid "Enable {0} only"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:97
|
||||
msgid "Enable External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:144
|
||||
msgid "Enable this setting to only see replies between people you follow."
|
||||
msgstr ""
|
||||
|
||||
@@ -857,6 +870,20 @@ msgstr ""
|
||||
msgid "Expand alt text"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:64
|
||||
msgid "External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:75
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:66
|
||||
msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:52
|
||||
#: src/view/screens/Settings.tsx:595
|
||||
msgid "External Media Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141
|
||||
msgid "Failed to load recommended feeds"
|
||||
@@ -904,7 +931,7 @@ msgstr ""
|
||||
msgid "Finding similar accounts..."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:102
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:108
|
||||
msgid "Fine-tune the content you see on your home screen."
|
||||
msgstr ""
|
||||
|
||||
@@ -928,7 +955,7 @@ msgstr ""
|
||||
msgid "Followed users"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:145
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:151
|
||||
msgid "Followed users only"
|
||||
msgstr ""
|
||||
|
||||
@@ -957,11 +984,11 @@ msgstr ""
|
||||
msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:232
|
||||
#: src/view/com/auth/login/LoginForm.tsx:236
|
||||
msgid "Forgot"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:229
|
||||
#: src/view/com/auth/login/LoginForm.tsx:233
|
||||
msgid "Forgot password"
|
||||
msgstr ""
|
||||
|
||||
@@ -993,7 +1020,7 @@ msgid "Go Back"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:181
|
||||
#: src/view/com/auth/login/LoginForm.tsx:279
|
||||
#: src/view/com/auth/login/LoginForm.tsx:283
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:163
|
||||
msgid "Go to next"
|
||||
msgstr ""
|
||||
@@ -1064,7 +1091,7 @@ msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:96
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:95
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:101
|
||||
#: src/view/screens/Settings.tsx:481
|
||||
msgid "Home Feed Preferences"
|
||||
msgstr ""
|
||||
@@ -1104,7 +1131,7 @@ msgstr ""
|
||||
#~ msgid "In Your Network"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:113
|
||||
#: src/view/com/auth/login/LoginForm.tsx:115
|
||||
msgid "Invalid username or password"
|
||||
msgstr ""
|
||||
|
||||
@@ -1329,6 +1356,10 @@ msgstr ""
|
||||
#~ msgid "More post options"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:82
|
||||
msgid "Most-liked replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/profile/ProfileHeader.tsx:370
|
||||
msgid "Mute Account"
|
||||
msgstr ""
|
||||
@@ -1390,6 +1421,11 @@ msgstr ""
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:107
|
||||
#: src/view/com/modals/EmbedConsent.tsx:123
|
||||
msgid "Never load embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72
|
||||
msgid "Never lose access to your followers and data."
|
||||
msgstr ""
|
||||
@@ -1413,10 +1449,14 @@ msgstr ""
|
||||
msgid "New Post"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:79
|
||||
msgid "Newest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:154
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:174
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:184
|
||||
#: src/view/com/auth/login/LoginForm.tsx:282
|
||||
#: src/view/com/auth/login/LoginForm.tsx:286
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:156
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:166
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79
|
||||
@@ -1427,10 +1467,12 @@ msgstr ""
|
||||
msgid "Next image"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:191
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:226
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:263
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:197
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:232
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:269
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
@@ -1460,6 +1502,10 @@ msgstr ""
|
||||
msgid "No results found for {query}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:129
|
||||
msgid "No thanks"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:82
|
||||
msgid "Nobody"
|
||||
msgstr ""
|
||||
@@ -1501,7 +1547,11 @@ msgstr ""
|
||||
msgid "Okay"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:358
|
||||
#: src/view/screens/PreferencesThreads.tsx:78
|
||||
msgid "Oldest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:363
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr ""
|
||||
|
||||
@@ -1509,6 +1559,11 @@ msgstr ""
|
||||
msgid "Only {0} can reply."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
#: src/view/com/composer/Composer.tsx:469
|
||||
msgid "Open emoji picker"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:76
|
||||
msgid "Open navigation"
|
||||
msgstr ""
|
||||
@@ -1517,6 +1572,10 @@ msgstr ""
|
||||
msgid "Opens configurable language settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:587
|
||||
msgid "Opens external embeds settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:156
|
||||
#: src/view/shell/Drawer.tsx:641
|
||||
msgid "Opens list of invite codes"
|
||||
@@ -1534,7 +1593,7 @@ msgstr ""
|
||||
msgid "Opens screen with all saved feeds"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:581
|
||||
#: src/view/screens/Settings.tsx:614
|
||||
msgid "Opens the app password settings page"
|
||||
msgstr ""
|
||||
|
||||
@@ -1542,11 +1601,11 @@ msgstr ""
|
||||
msgid "Opens the home feed preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:664
|
||||
#: src/view/screens/Settings.tsx:697
|
||||
msgid "Opens the storybook page"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:644
|
||||
#: src/view/screens/Settings.tsx:677
|
||||
msgid "Opens the system log page"
|
||||
msgstr ""
|
||||
|
||||
@@ -1577,7 +1636,7 @@ msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:122
|
||||
#: src/view/com/auth/create/Step2.tsx:132
|
||||
#: src/view/com/auth/login/LoginForm.tsx:217
|
||||
#: src/view/com/auth/login/LoginForm.tsx:221
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:130
|
||||
#: src/view/com/modals/DeleteAccount.tsx:191
|
||||
msgid "Password"
|
||||
@@ -1599,6 +1658,19 @@ msgstr ""
|
||||
msgid "Pinned Feeds"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111
|
||||
msgid "Play {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55
|
||||
msgid "Play Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110
|
||||
msgid "Plays the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:116
|
||||
msgid "Please choose your handle."
|
||||
msgstr ""
|
||||
@@ -1633,11 +1705,11 @@ msgstr ""
|
||||
#~ msgid "Please tell us why you think this decision was incorrect."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:214
|
||||
#: src/view/com/composer/Composer.tsx:215
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:341
|
||||
#: src/view/com/composer/Composer.tsx:346
|
||||
#: src/view/com/post-thread/PostThread.tsx:225
|
||||
#: src/view/screens/PostThread.tsx:80
|
||||
msgid "Post"
|
||||
@@ -1675,16 +1747,17 @@ msgstr ""
|
||||
msgid "Primary Language"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:91
|
||||
#: src/view/screens/PreferencesThreads.tsx:97
|
||||
msgid "Prioritize Your Follows"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:570
|
||||
#: src/view/shell/desktop/RightNav.tsx:84
|
||||
msgid "Privacy"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PrivacyPolicy.tsx:29
|
||||
#: src/view/screens/Settings.tsx:750
|
||||
#: src/view/screens/Settings.tsx:783
|
||||
#: src/view/shell/Drawer.tsx:262
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
@@ -1701,7 +1774,7 @@ msgstr ""
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:808
|
||||
#: src/view/screens/Settings.tsx:841
|
||||
msgid "Protect your account by verifying your email."
|
||||
msgstr ""
|
||||
|
||||
@@ -1722,6 +1795,10 @@ msgstr ""
|
||||
msgid "Quote Post"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:86
|
||||
msgid "Random (aka \"Poster's Roulette\")"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EditImage.tsx:236
|
||||
msgid "Ratios"
|
||||
msgstr ""
|
||||
@@ -1794,7 +1871,7 @@ msgstr ""
|
||||
msgid "Replies to this thread are disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:135
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:141
|
||||
msgid "Reply Filters"
|
||||
msgstr ""
|
||||
|
||||
@@ -1841,9 +1918,9 @@ msgstr ""
|
||||
#~ msgid "Request to limit the visibility of my account"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:382
|
||||
#~ msgid "Require alt text before posting"
|
||||
#~ msgstr ""
|
||||
#: src/view/screens/Settings.tsx:422
|
||||
msgid "Require alt text before posting"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:68
|
||||
msgid "Required for this provider"
|
||||
@@ -1853,7 +1930,7 @@ msgstr ""
|
||||
msgid "Reset code"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:686
|
||||
#: src/view/screens/Settings.tsx:719
|
||||
msgid "Reset onboarding state"
|
||||
msgstr ""
|
||||
|
||||
@@ -1861,22 +1938,22 @@ msgstr ""
|
||||
msgid "Reset password"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:676
|
||||
#: src/view/screens/Settings.tsx:709
|
||||
msgid "Reset preferences state"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:684
|
||||
#: src/view/screens/Settings.tsx:717
|
||||
msgid "Resets the onboarding state"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:674
|
||||
#: src/view/screens/Settings.tsx:707
|
||||
msgid "Resets the preferences state"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:163
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:167
|
||||
#: src/view/com/auth/login/LoginForm.tsx:259
|
||||
#: src/view/com/auth/login/LoginForm.tsx:262
|
||||
#: src/view/com/auth/login/LoginForm.tsx:263
|
||||
#: src/view/com/auth/login/LoginForm.tsx:266
|
||||
#: src/view/com/util/error/ErrorMessage.tsx:55
|
||||
#: src/view/com/util/error/ErrorScreen.tsx:65
|
||||
msgid "Retry"
|
||||
@@ -1886,7 +1963,6 @@ msgstr ""
|
||||
#~ msgid "Retry change handle"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:94
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:97
|
||||
#: src/view/com/modals/ChangeHandle.tsx:173
|
||||
@@ -1958,7 +2034,7 @@ msgstr ""
|
||||
msgid "Select from an existing account"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:143
|
||||
#: src/view/com/auth/login/LoginForm.tsx:147
|
||||
msgid "Select service"
|
||||
msgstr ""
|
||||
|
||||
@@ -1999,23 +2075,23 @@ msgstr ""
|
||||
msgid "Set new password"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:216
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:222
|
||||
msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:113
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:119
|
||||
msgid "Set this setting to \"No\" to hide all replies from your feed."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:182
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:188
|
||||
msgid "Set this setting to \"No\" to hide all reposts from your feed."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:116
|
||||
#: src/view/screens/PreferencesThreads.tsx:122
|
||||
msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:252
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:258
|
||||
msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature."
|
||||
msgstr ""
|
||||
|
||||
@@ -2053,23 +2129,27 @@ msgstr ""
|
||||
msgid "Show anyway"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:249
|
||||
#: src/view/com/modals/EmbedConsent.tsx:87
|
||||
msgid "Show embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:255
|
||||
msgid "Show Posts from My Feeds"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:213
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:219
|
||||
msgid "Show Quote Posts"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:110
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:116
|
||||
msgid "Show Replies"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:94
|
||||
#: src/view/screens/PreferencesThreads.tsx:100
|
||||
msgid "Show replies by people you follow before all other replies."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:179
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:185
|
||||
msgid "Show Reposts"
|
||||
msgstr ""
|
||||
|
||||
@@ -2106,7 +2186,7 @@ msgstr ""
|
||||
msgid "Sign in as..."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:130
|
||||
#: src/view/com/auth/login/LoginForm.tsx:134
|
||||
msgid "Sign into"
|
||||
msgstr ""
|
||||
|
||||
@@ -2160,11 +2240,11 @@ msgstr ""
|
||||
msgid "Staging"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:730
|
||||
#: src/view/screens/Settings.tsx:763
|
||||
msgid "Status page"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:666
|
||||
#: src/view/screens/Settings.tsx:699
|
||||
msgid "Storybook"
|
||||
msgstr ""
|
||||
|
||||
@@ -2197,7 +2277,7 @@ msgstr ""
|
||||
#~ msgid "System"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:646
|
||||
#: src/view/screens/Settings.tsx:679
|
||||
msgid "System log"
|
||||
msgstr ""
|
||||
|
||||
@@ -2209,7 +2289,7 @@ msgstr ""
|
||||
msgid "Terms"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:744
|
||||
#: src/view/screens/Settings.tsx:777
|
||||
#: src/view/screens/TermsOfService.tsx:29
|
||||
#: src/view/shell/Drawer.tsx:256
|
||||
msgid "Terms of Service"
|
||||
@@ -2264,6 +2344,10 @@ msgstr ""
|
||||
msgid "This account has requested that users sign in to view their profile."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:68
|
||||
msgid "This content is hosted by {0}. Do you want to enable external media?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/posts/FeedErrorMessage.tsx:107
|
||||
msgid "This content is not viewable without a Bluesky account."
|
||||
msgstr ""
|
||||
@@ -2305,7 +2389,7 @@ msgstr ""
|
||||
msgid "Thread Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:113
|
||||
#: src/view/screens/PreferencesThreads.tsx:119
|
||||
msgid "Threaded Mode"
|
||||
msgstr ""
|
||||
|
||||
@@ -2337,7 +2421,7 @@ msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:65
|
||||
#: src/view/com/auth/login/Login.tsx:76
|
||||
#: src/view/com/auth/login/LoginForm.tsx:117
|
||||
#: src/view/com/auth/login/LoginForm.tsx:120
|
||||
msgid "Unable to contact your service. Please check your Internet connection."
|
||||
msgstr ""
|
||||
|
||||
@@ -2355,7 +2439,7 @@ msgstr ""
|
||||
msgid "Undo repost"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:210
|
||||
#: src/view/com/auth/create/state.ts:216
|
||||
msgid "Unfortunately, you do not meet the requirements to create an account."
|
||||
msgstr ""
|
||||
|
||||
@@ -2411,8 +2495,8 @@ msgstr ""
|
||||
msgid "User Lists"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:170
|
||||
#: src/view/com/auth/login/LoginForm.tsx:188
|
||||
#: src/view/com/auth/login/LoginForm.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:192
|
||||
msgid "Username or email address"
|
||||
msgstr ""
|
||||
|
||||
@@ -2432,15 +2516,15 @@ msgstr ""
|
||||
msgid "Users in \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:769
|
||||
#: src/view/screens/Settings.tsx:802
|
||||
msgid "Verify email"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:794
|
||||
#: src/view/screens/Settings.tsx:827
|
||||
msgid "Verify my email"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:803
|
||||
#: src/view/screens/Settings.tsx:836
|
||||
msgid "Verify My Email"
|
||||
msgstr ""
|
||||
|
||||
@@ -2514,7 +2598,7 @@ msgstr ""
|
||||
msgid "Wide"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:413
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
msgid "Write post"
|
||||
msgstr ""
|
||||
|
||||
@@ -2522,10 +2606,12 @@ msgstr ""
|
||||
msgid "Write your reply"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:192
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:227
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:262
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:198
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:233
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:268
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+197
-128
@@ -15,7 +15,7 @@ msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:168
|
||||
msgid "{0, plural, one {# invite code available} other {# invite codes available}}"
|
||||
msgstr ""
|
||||
msgstr "{0, plural, one {# invite code available} other {# invite codes available}}"
|
||||
|
||||
#: src/view/com/modals/Repost.tsx:44
|
||||
msgid "{0}"
|
||||
@@ -27,7 +27,7 @@ msgstr "Lista {purposeLabel} {0}"
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:151
|
||||
msgid "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}"
|
||||
msgstr ""
|
||||
msgstr "{invitesAvailable, plural, one {Invite codes: # available} other {Invite codes: # available}}"
|
||||
|
||||
#: src/view/screens/Settings.tsx:407
|
||||
#: src/view/shell/Drawer.tsx:659
|
||||
@@ -57,7 +57,7 @@ msgstr "<0>Sigue a algunos</0><1>usuarios</1><2>recomendados</2>"
|
||||
|
||||
#: src/view/com/util/moderation/LabelInfo.tsx:45
|
||||
msgid "A content warning has been applied to this {0}."
|
||||
msgstr ""
|
||||
msgstr "Se ha aplicado una advertencia de contenido a este {0}."
|
||||
|
||||
#: src/lib/hooks/useOTAUpdate.ts:16
|
||||
msgid "A new version of the app is available. Please update to continue using the app."
|
||||
@@ -68,7 +68,7 @@ msgstr "Ya está disponible una nueva versión de la aplicación. Actualízala p
|
||||
msgid "Accessibility"
|
||||
msgstr "Accesibilidad"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:159
|
||||
#: src/view/com/auth/login/LoginForm.tsx:163
|
||||
#: src/view/screens/Settings.tsx:286
|
||||
msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
@@ -98,6 +98,7 @@ msgstr "Agregar una cuenta"
|
||||
|
||||
#: src/view/com/composer/photos/Gallery.tsx:119
|
||||
#: src/view/com/composer/photos/Gallery.tsx:180
|
||||
#: src/view/com/modals/AltImage.tsx:93
|
||||
msgid "Add alt text"
|
||||
msgstr "Agregar texto alt"
|
||||
|
||||
@@ -110,11 +111,11 @@ msgstr "Agregar detalles"
|
||||
msgid "Add details to report"
|
||||
msgstr "Agregar detalles al informe"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:442
|
||||
#: src/view/com/composer/Composer.tsx:447
|
||||
msgid "Add link card"
|
||||
msgstr "Agregar una tarjeta de enlace"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:445
|
||||
#: src/view/com/composer/Composer.tsx:450
|
||||
msgid "Add link card:"
|
||||
msgstr "Agregar una tarjeta de enlace:"
|
||||
|
||||
@@ -135,7 +136,7 @@ msgstr "Agregar a mis noticias"
|
||||
msgid "Added to list"
|
||||
msgstr "Agregar a una lista"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:164
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:170
|
||||
msgid "Adjust the number of likes a reply must have to be shown in your feed."
|
||||
msgstr "Ajusta el número de Me gusta que debe tener una respuesta para que se muestre en tus noticias."
|
||||
|
||||
@@ -143,7 +144,7 @@ msgstr "Ajusta el número de Me gusta que debe tener una respuesta para que se m
|
||||
msgid "Adult Content"
|
||||
msgstr "Contenido para adultos"
|
||||
|
||||
#: src/view/screens/Settings.tsx:569
|
||||
#: src/view/screens/Settings.tsx:602
|
||||
msgid "Advanced"
|
||||
msgstr "Avanzado"
|
||||
|
||||
@@ -176,7 +177,7 @@ msgstr "y"
|
||||
msgid "App Language"
|
||||
msgstr "Lenguaje de app"
|
||||
|
||||
#: src/view/screens/Settings.tsx:589
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
msgid "App passwords"
|
||||
msgstr "Contraseñas de la app"
|
||||
|
||||
@@ -186,15 +187,11 @@ msgstr "Contraseñas de la app"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:236
|
||||
msgid "Appeal content warning"
|
||||
msgstr ""
|
||||
msgstr "Aviso sobre el contenido del recurso"
|
||||
|
||||
#: src/view/com/modals/AppealLabel.tsx:65
|
||||
msgid "Appeal Content Warning"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/AppealLabel.tsx:65
|
||||
#~ msgid "Appeal Decision"
|
||||
#~ msgstr "Decisión de apelación"
|
||||
msgstr "Aviso sobre el Contenido del Recurso"
|
||||
|
||||
#: src/view/com/util/moderation/LabelInfo.tsx:52
|
||||
msgid "Appeal this decision"
|
||||
@@ -212,7 +209,7 @@ 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:142
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr "¿Estás seguro de que quieres descartar este borrador?"
|
||||
|
||||
@@ -222,7 +219,7 @@ msgstr "¿Estás seguro?"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:219
|
||||
msgid "Are you sure? This cannot be undone."
|
||||
msgstr "¿Estás seguro? Esto no puede deshacerse,"
|
||||
msgstr "¿Estás seguro? Esto no puede deshacerse."
|
||||
|
||||
#: src/view/com/modals/SelfLabel.tsx:123
|
||||
msgid "Artistic or non-erotic nudity."
|
||||
@@ -231,7 +228,7 @@ msgstr "Desnudez artística o no erótica."
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:141
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:151
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:166
|
||||
#: src/view/com/auth/login/LoginForm.tsx:250
|
||||
#: src/view/com/auth/login/LoginForm.tsx:254
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:148
|
||||
#: src/view/com/modals/report/InputIssueDetails.tsx:46
|
||||
#: src/view/com/post-thread/PostThread.tsx:388
|
||||
@@ -289,7 +286,7 @@ msgstr "Las cuentas bloqueadas no pueden responder en tus hilos, mencionarte ni
|
||||
|
||||
#: src/view/com/post-thread/PostThread.tsx:250
|
||||
msgid "Blocked post."
|
||||
msgstr "Publicación bloqueada"
|
||||
msgstr "Publicación bloqueada."
|
||||
|
||||
#: src/view/screens/ProfileList.tsx:310
|
||||
msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
|
||||
@@ -327,7 +324,7 @@ msgstr "Bluesky no mostrará tu perfil ni tus publicaciones a los usuarios que h
|
||||
msgid "Bluesky.Social"
|
||||
msgstr "Bluesky.Social"
|
||||
|
||||
#: src/view/screens/Settings.tsx:718
|
||||
#: src/view/screens/Settings.tsx:751
|
||||
msgid "Build version {0} {1}"
|
||||
msgstr "Versión {0} {1}"
|
||||
|
||||
@@ -345,9 +342,8 @@ msgstr "Cámara"
|
||||
msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long."
|
||||
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/view/com/composer/Composer.tsx:289
|
||||
#: src/view/com/composer/Composer.tsx:292
|
||||
#: src/view/com/modals/AltImage.tsx:128
|
||||
#: src/view/com/composer/Composer.tsx:294
|
||||
#: src/view/com/composer/Composer.tsx:297
|
||||
#: src/view/com/modals/ChangeEmail.tsx:218
|
||||
#: src/view/com/modals/ChangeEmail.tsx:220
|
||||
#: src/view/com/modals/Confirm.tsx:88
|
||||
@@ -371,8 +367,8 @@ msgid "Cancel account deletion"
|
||||
msgstr "Cancelar la eliminación de la cuenta"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:123
|
||||
msgid "Cancel add image alt text"
|
||||
msgstr "Cancelar añadir texto alternativo a la imagen"
|
||||
#~ msgid "Cancel add image alt text"
|
||||
#~ msgstr "Cancelar añadir texto alternativo a la imagen"
|
||||
|
||||
#: src/view/com/modals/ChangeHandle.tsx:149
|
||||
msgid "Cancel change handle"
|
||||
@@ -403,8 +399,8 @@ msgstr "Cancelar la inscripción en la lista de espera"
|
||||
msgid "Change"
|
||||
msgstr "Cambiar"
|
||||
|
||||
#: src/view/screens/Settings.tsx:601
|
||||
#: src/view/screens/Settings.tsx:610
|
||||
#: src/view/screens/Settings.tsx:634
|
||||
#: src/view/screens/Settings.tsx:643
|
||||
msgid "Change handle"
|
||||
msgstr "Cambiar el identificador"
|
||||
|
||||
@@ -448,19 +444,19 @@ msgstr "Elige los algoritmos que potencian tu experiencia con publicaciones pers
|
||||
msgid "Choose your password"
|
||||
msgstr "Elige tu contraseña"
|
||||
|
||||
#: src/view/screens/Settings.tsx:694
|
||||
#: src/view/screens/Settings.tsx:727
|
||||
msgid "Clear all legacy storage data"
|
||||
msgstr "Borrar todos los datos de almacenamiento heredados"
|
||||
|
||||
#: src/view/screens/Settings.tsx:696
|
||||
#: src/view/screens/Settings.tsx:729
|
||||
msgid "Clear all legacy storage data (restart after this)"
|
||||
msgstr "Borrar todos los datos de almacenamiento heredados (reiniciar después de esto)"
|
||||
|
||||
#: src/view/screens/Settings.tsx:706
|
||||
#: src/view/screens/Settings.tsx:739
|
||||
msgid "Clear all storage data"
|
||||
msgstr "Borrar todos los datos de almacenamiento"
|
||||
|
||||
#: src/view/screens/Settings.tsx:708
|
||||
#: src/view/screens/Settings.tsx:741
|
||||
msgid "Clear all storage data (restart after this)"
|
||||
msgstr "Borrar todos los datos de almacenamiento (reiniciar después de esto)"
|
||||
|
||||
@@ -501,8 +497,8 @@ msgstr "Redactar la respuesta"
|
||||
#: src/view/com/modals/Confirm.tsx:75
|
||||
#: src/view/com/modals/SelfLabel.tsx:154
|
||||
#: src/view/com/modals/VerifyEmail.tsx:225
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:299
|
||||
#: src/view/screens/PreferencesThreads.tsx:153
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:305
|
||||
#: src/view/screens/PreferencesThreads.tsx:159
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
@@ -526,7 +522,7 @@ msgid "Confirmation code"
|
||||
msgstr "Código de confirmación"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:269
|
||||
#: src/view/com/auth/login/LoginForm.tsx:273
|
||||
msgid "Connecting..."
|
||||
msgstr "Conectando..."
|
||||
|
||||
@@ -616,11 +612,15 @@ msgstr "Creado {0}"
|
||||
msgid "Custom domain"
|
||||
msgstr "Dominio personalizado"
|
||||
|
||||
#: src/view/screens/Settings.tsx:615
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:55
|
||||
msgid "Customize media from external sites."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:648
|
||||
msgid "Danger Zone"
|
||||
msgstr "Zona de peligro"
|
||||
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
#: src/view/screens/Settings.tsx:655
|
||||
msgid "Delete account"
|
||||
msgstr "Borrar la cuenta"
|
||||
|
||||
@@ -642,7 +642,7 @@ msgstr "Borrar la lista"
|
||||
msgid "Delete my account"
|
||||
msgstr "Borrar mi cuenta"
|
||||
|
||||
#: src/view/screens/Settings.tsx:632
|
||||
#: src/view/screens/Settings.tsx:665
|
||||
msgid "Delete my account…"
|
||||
msgstr "Borrar mi cuenta..."
|
||||
|
||||
@@ -669,19 +669,19 @@ msgstr "Descripción"
|
||||
msgid "Dev Server"
|
||||
msgstr "Servidor de desarrollo"
|
||||
|
||||
#: src/view/screens/Settings.tsx:637
|
||||
#: src/view/screens/Settings.tsx:670
|
||||
msgid "Developer Tools"
|
||||
msgstr "Herramientas de desarrollador"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:210
|
||||
#: src/view/com/composer/Composer.tsx:211
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
msgstr "¿Quieres decir algo?"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
#: src/view/com/composer/Composer.tsx:144
|
||||
msgid "Discard"
|
||||
msgstr "Descartar"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:137
|
||||
#: src/view/com/composer/Composer.tsx:138
|
||||
msgid "Discard draft"
|
||||
msgstr "Descartar el borrador"
|
||||
|
||||
@@ -706,6 +706,7 @@ msgid "Domain verified!"
|
||||
msgstr "¡Dominio verificado!"
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:88
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:96
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:152
|
||||
@@ -715,8 +716,8 @@ msgstr "¡Dominio verificado!"
|
||||
#: src/view/com/modals/Threadgate.tsx:129
|
||||
#: src/view/com/modals/Threadgate.tsx:132
|
||||
#: src/view/com/modals/UserAddRemoveLists.tsx:79
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:302
|
||||
#: src/view/screens/PreferencesThreads.tsx:156
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:308
|
||||
#: src/view/screens/PreferencesThreads.tsx:162
|
||||
msgid "Done"
|
||||
msgstr "Listo"
|
||||
|
||||
@@ -777,7 +778,15 @@ msgstr "Correo electrónico actualizado"
|
||||
msgid "Email:"
|
||||
msgstr "Correo electrónico:"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:138
|
||||
#: src/view/com/modals/EmbedConsent.tsx:113
|
||||
msgid "Enable {0} only"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:97
|
||||
msgid "Enable External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:144
|
||||
msgid "Enable this setting to only see replies between people you follow."
|
||||
msgstr "Activa esta opción para ver sólo las respuestas de las personas a las que sigues."
|
||||
|
||||
@@ -821,6 +830,20 @@ msgstr "Todos"
|
||||
msgid "Expand alt text"
|
||||
msgstr "Expandir el texto alt"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:64
|
||||
msgid "External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:75
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:66
|
||||
msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:52
|
||||
#: src/view/screens/Settings.tsx:595
|
||||
msgid "External Media Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141
|
||||
msgid "Failed to load recommended feeds"
|
||||
@@ -868,7 +891,7 @@ msgstr "Encuentra usuarios con la herramienta de búsqueda de la derecha"
|
||||
msgid "Finding similar accounts..."
|
||||
msgstr "Encontrar cuentas similares..."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:102
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:108
|
||||
msgid "Fine-tune the content you see on your home screen."
|
||||
msgstr "Ajusta el contenido que ves en tu pantalla de inicio."
|
||||
|
||||
@@ -888,7 +911,7 @@ msgstr "Sigue a algunos usuarios para empezar. Podemos recomendarte más usuario
|
||||
msgid "Followed users"
|
||||
msgstr "Usuarios seguidos"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:145
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:151
|
||||
msgid "Followed users only"
|
||||
msgstr "Solo usuarios seguidos"
|
||||
|
||||
@@ -917,11 +940,11 @@ msgstr "Por razones de seguridad, tendremos que enviarte un código de confirmac
|
||||
msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one."
|
||||
msgstr "Por razones de seguridad, no podrás volver a verla. Si pierdes esta contraseña, tendrás que generar una nueva."
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:232
|
||||
#: src/view/com/auth/login/LoginForm.tsx:236
|
||||
msgid "Forgot"
|
||||
msgstr "Lo olvidé"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:229
|
||||
#: src/view/com/auth/login/LoginForm.tsx:233
|
||||
msgid "Forgot password"
|
||||
msgstr "Olvidé mi contraseña"
|
||||
|
||||
@@ -953,7 +976,7 @@ msgid "Go Back"
|
||||
msgstr "Regresar"
|
||||
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:181
|
||||
#: src/view/com/auth/login/LoginForm.tsx:279
|
||||
#: src/view/com/auth/login/LoginForm.tsx:283
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:163
|
||||
msgid "Go to next"
|
||||
msgstr "Ir al siguiente"
|
||||
@@ -978,11 +1001,11 @@ msgstr "Ocultar"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:173
|
||||
msgid "Hide post"
|
||||
msgstr ""
|
||||
msgstr "Ocultar publicación"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:177
|
||||
msgid "Hide this post?"
|
||||
msgstr ""
|
||||
msgstr "¿Ocultar esta publicación?"
|
||||
|
||||
#: src/view/com/notifications/FeedItem.tsx:316
|
||||
msgid "Hide user list"
|
||||
@@ -1016,7 +1039,7 @@ msgid "Home"
|
||||
msgstr "Página inicial"
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:96
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:95
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:101
|
||||
#: src/view/screens/Settings.tsx:481
|
||||
msgid "Home Feed Preferences"
|
||||
msgstr "Preferencias de noticias de la página inicial"
|
||||
@@ -1051,7 +1074,7 @@ msgstr "Texto alt de la imagen"
|
||||
msgid "Image options"
|
||||
msgstr "Opciones de la imagen"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:113
|
||||
#: src/view/com/auth/login/LoginForm.tsx:115
|
||||
msgid "Invalid username or password"
|
||||
msgstr "Nombre de usuario o contraseña no válidos"
|
||||
|
||||
@@ -1202,10 +1225,6 @@ msgstr "Visibilidad de desconexión"
|
||||
msgid "Login to account that is not listed"
|
||||
msgstr "Acceder a una cuenta que no está en la lista"
|
||||
|
||||
#: src/view/screens/ProfileFeed.tsx:472
|
||||
#~ msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
|
||||
#~ msgstr "Parece que este canal de noticias sólo está disponible para usuarios con una cuenta Bluesky. Por favor, ¡regístrate o inicia sesión para ver este canal!"
|
||||
|
||||
#: src/view/com/modals/LinkWarning.tsx:63
|
||||
msgid "Make sure this is where you intend to go!"
|
||||
msgstr "¡Asegúrate de que es aquí a donde pretendes ir!"
|
||||
@@ -1256,6 +1275,10 @@ msgstr "Más canales de noticias"
|
||||
msgid "More options"
|
||||
msgstr "Más opciones"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:82
|
||||
msgid "Most-liked replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/profile/ProfileHeader.tsx:370
|
||||
msgid "Mute Account"
|
||||
msgstr "Silenciar la cuenta"
|
||||
@@ -1313,6 +1336,11 @@ msgstr "Mis canales de noticias guardados"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:107
|
||||
#: src/view/com/modals/EmbedConsent.tsx:123
|
||||
msgid "Never load embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72
|
||||
msgid "Never lose access to your followers and data."
|
||||
msgstr "No pierdas nunca el acceso a tus seguidores y datos."
|
||||
@@ -1336,10 +1364,14 @@ msgstr "Publicación nueva"
|
||||
msgid "New Post"
|
||||
msgstr "Publicación nueva"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:79
|
||||
msgid "Newest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:154
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:174
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:184
|
||||
#: src/view/com/auth/login/LoginForm.tsx:282
|
||||
#: src/view/com/auth/login/LoginForm.tsx:286
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:156
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:166
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79
|
||||
@@ -1350,10 +1382,12 @@ msgstr "Siguiente"
|
||||
msgid "Next image"
|
||||
msgstr "Imagen nueva"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:191
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:226
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:263
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:197
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:232
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:269
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
@@ -1378,6 +1412,10 @@ msgstr "No se han encontrado resultados para \"{query}\""
|
||||
msgid "No results found for {query}"
|
||||
msgstr "No se han encontrado resultados para {query}"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:129
|
||||
msgid "No thanks"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:82
|
||||
msgid "Nobody"
|
||||
msgstr "Nadie"
|
||||
@@ -1407,7 +1445,11 @@ msgstr "¡Qué problema!"
|
||||
msgid "Okay"
|
||||
msgstr "Está bien"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:358
|
||||
#: src/view/screens/PreferencesThreads.tsx:78
|
||||
msgid "Oldest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:363
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr "Falta el texto alternativo en una o varias imágenes."
|
||||
|
||||
@@ -1415,6 +1457,11 @@ msgstr "Falta el texto alternativo en una o varias imágenes."
|
||||
msgid "Only {0} can reply."
|
||||
msgstr "Solo {0} puede responder."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
#: src/view/com/composer/Composer.tsx:469
|
||||
msgid "Open emoji picker"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:76
|
||||
msgid "Open navigation"
|
||||
msgstr "Abrir navegación"
|
||||
@@ -1423,6 +1470,10 @@ msgstr "Abrir navegación"
|
||||
msgid "Opens configurable language settings"
|
||||
msgstr "Abrir la configuración del idioma que se puede ajustar"
|
||||
|
||||
#: src/view/screens/Settings.tsx:587
|
||||
msgid "Opens external embeds settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:156
|
||||
#: src/view/shell/Drawer.tsx:641
|
||||
msgid "Opens list of invite codes"
|
||||
@@ -1440,7 +1491,7 @@ msgstr "Abre la configuración de moderación"
|
||||
msgid "Opens screen with all saved feeds"
|
||||
msgstr "Abre la pantalla con todas las noticias guardadas"
|
||||
|
||||
#: src/view/screens/Settings.tsx:581
|
||||
#: src/view/screens/Settings.tsx:614
|
||||
msgid "Opens the app password settings page"
|
||||
msgstr "Abre la página de configuración de la contraseña de la app"
|
||||
|
||||
@@ -1448,11 +1499,11 @@ msgstr "Abre la página de configuración de la contraseña de la app"
|
||||
msgid "Opens the home feed preferences"
|
||||
msgstr "Abre las preferencias de noticias de la página inicial"
|
||||
|
||||
#: src/view/screens/Settings.tsx:664
|
||||
#: src/view/screens/Settings.tsx:697
|
||||
msgid "Opens the storybook page"
|
||||
msgstr "Abre la página del libro de cuentos"
|
||||
|
||||
#: src/view/screens/Settings.tsx:644
|
||||
#: src/view/screens/Settings.tsx:677
|
||||
msgid "Opens the system log page"
|
||||
msgstr "Abre la página de la bitácora del sistema"
|
||||
|
||||
@@ -1483,7 +1534,7 @@ msgstr "Página no encontrada"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:122
|
||||
#: src/view/com/auth/create/Step2.tsx:132
|
||||
#: src/view/com/auth/login/LoginForm.tsx:217
|
||||
#: src/view/com/auth/login/LoginForm.tsx:221
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:130
|
||||
#: src/view/com/modals/DeleteAccount.tsx:191
|
||||
msgid "Password"
|
||||
@@ -1505,6 +1556,19 @@ msgstr "Imágenes destinadas a adultos."
|
||||
msgid "Pinned Feeds"
|
||||
msgstr "Canales de noticias anclados"
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111
|
||||
msgid "Play {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55
|
||||
msgid "Play Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110
|
||||
msgid "Plays the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:116
|
||||
msgid "Please choose your handle."
|
||||
msgstr "Por favor, elige tu identificador."
|
||||
@@ -1532,18 +1596,13 @@ msgstr "Introduce tu contraseña, también:"
|
||||
#: src/view/com/modals/AppealLabel.tsx:72
|
||||
#: src/view/com/modals/AppealLabel.tsx:75
|
||||
msgid "Please tell us why you think this content warning was incorrectly applied!"
|
||||
msgstr ""
|
||||
msgstr "Por favor, dinos por qué crees que esta advertencia de contenido se ha aplicado incorrectamente!"
|
||||
|
||||
#: src/view/com/modals/AppealLabel.tsx:72
|
||||
#: src/view/com/modals/AppealLabel.tsx:75
|
||||
#~ msgid "Please tell us why you think this decision was incorrect."
|
||||
#~ msgstr "Por favor, dinos por qué crees que esta decisión fue incorrecta."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:214
|
||||
#: src/view/com/composer/Composer.tsx:215
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
msgstr "Por favor, espera a que tu tarjeta de enlace termine de cargarse"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:341
|
||||
#: src/view/com/composer/Composer.tsx:346
|
||||
#: src/view/com/post-thread/PostThread.tsx:225
|
||||
#: src/view/screens/PostThread.tsx:80
|
||||
msgid "Post"
|
||||
@@ -1581,16 +1640,17 @@ msgstr "Imagen previa"
|
||||
msgid "Primary Language"
|
||||
msgstr "Lenguajes primarios"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:91
|
||||
#: src/view/screens/PreferencesThreads.tsx:97
|
||||
msgid "Prioritize Your Follows"
|
||||
msgstr "Priorizar los usuarios a los que sigue"
|
||||
|
||||
#: src/view/screens/Settings.tsx:570
|
||||
#: src/view/shell/desktop/RightNav.tsx:84
|
||||
msgid "Privacy"
|
||||
msgstr "Privacidad"
|
||||
|
||||
#: src/view/screens/PrivacyPolicy.tsx:29
|
||||
#: src/view/screens/Settings.tsx:750
|
||||
#: src/view/screens/Settings.tsx:783
|
||||
#: src/view/shell/Drawer.tsx:262
|
||||
msgid "Privacy Policy"
|
||||
msgstr "Política de privacidad"
|
||||
@@ -1607,7 +1667,7 @@ msgstr "Procesando..."
|
||||
msgid "Profile"
|
||||
msgstr "Perfil"
|
||||
|
||||
#: src/view/screens/Settings.tsx:808
|
||||
#: src/view/screens/Settings.tsx:841
|
||||
msgid "Protect your account by verifying your email."
|
||||
msgstr "Protege tu cuenta verificando tu correo electrónico."
|
||||
|
||||
@@ -1628,6 +1688,10 @@ msgstr "Citar una publicación"
|
||||
msgid "Quote Post"
|
||||
msgstr "Citar una publicación"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:86
|
||||
msgid "Random (aka \"Poster's Roulette\")"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EditImage.tsx:236
|
||||
msgid "Ratios"
|
||||
msgstr "Proporciones"
|
||||
@@ -1695,7 +1759,7 @@ msgstr "Respuestas"
|
||||
msgid "Replies to this thread are disabled"
|
||||
msgstr "Las respuestas a este hilo están desactivadas"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:135
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:141
|
||||
msgid "Reply Filters"
|
||||
msgstr "Filtros de respuestas"
|
||||
|
||||
@@ -1738,6 +1802,10 @@ msgstr "Vuelto a publicar por"
|
||||
msgid "Request Change"
|
||||
msgstr "Solicitar un cambio"
|
||||
|
||||
#: src/view/screens/Settings.tsx:422
|
||||
msgid "Require alt text before posting"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:68
|
||||
msgid "Required for this provider"
|
||||
msgstr "Requerido para este proveedor"
|
||||
@@ -1746,7 +1814,7 @@ msgstr "Requerido para este proveedor"
|
||||
msgid "Reset code"
|
||||
msgstr "Restablecer el código"
|
||||
|
||||
#: src/view/screens/Settings.tsx:686
|
||||
#: src/view/screens/Settings.tsx:719
|
||||
msgid "Reset onboarding state"
|
||||
msgstr "Restablecer el estado de incorporación"
|
||||
|
||||
@@ -1754,28 +1822,27 @@ msgstr "Restablecer el estado de incorporación"
|
||||
msgid "Reset password"
|
||||
msgstr "Restablecer la contraseña"
|
||||
|
||||
#: src/view/screens/Settings.tsx:676
|
||||
#: src/view/screens/Settings.tsx:709
|
||||
msgid "Reset preferences state"
|
||||
msgstr "Restablecer el estado de preferencias"
|
||||
|
||||
#: src/view/screens/Settings.tsx:684
|
||||
#: src/view/screens/Settings.tsx:717
|
||||
msgid "Resets the onboarding state"
|
||||
msgstr "Restablece el estado de incorporación"
|
||||
|
||||
#: src/view/screens/Settings.tsx:674
|
||||
#: src/view/screens/Settings.tsx:707
|
||||
msgid "Resets the preferences state"
|
||||
msgstr "Restablecer el estado de preferencias"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:163
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:167
|
||||
#: src/view/com/auth/login/LoginForm.tsx:259
|
||||
#: src/view/com/auth/login/LoginForm.tsx:262
|
||||
#: src/view/com/auth/login/LoginForm.tsx:263
|
||||
#: src/view/com/auth/login/LoginForm.tsx:266
|
||||
#: src/view/com/util/error/ErrorMessage.tsx:55
|
||||
#: src/view/com/util/error/ErrorScreen.tsx:65
|
||||
msgid "Retry"
|
||||
msgstr "Volver a intentar"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:94
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:97
|
||||
#: src/view/com/modals/ChangeHandle.tsx:173
|
||||
@@ -1821,7 +1888,7 @@ msgstr "Buscar"
|
||||
#: src/view/com/auth/LoggedOut.tsx:104
|
||||
#: src/view/com/auth/LoggedOut.tsx:105
|
||||
msgid "Search for users"
|
||||
msgstr ""
|
||||
msgstr "Buscar usuarios"
|
||||
|
||||
#: src/view/com/modals/ChangeEmail.tsx:110
|
||||
msgid "Security Step Required"
|
||||
@@ -1839,7 +1906,7 @@ msgstr "Seleccionar Bluesky Social"
|
||||
msgid "Select from an existing account"
|
||||
msgstr "Selecciona de una cuenta existente"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:143
|
||||
#: src/view/com/auth/login/LoginForm.tsx:147
|
||||
msgid "Select service"
|
||||
msgstr "Selecciona el servicio"
|
||||
|
||||
@@ -1880,23 +1947,23 @@ msgstr "Enviar el informe"
|
||||
msgid "Set new password"
|
||||
msgstr "Establecer la contraseña nueva"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:216
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:222
|
||||
msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible."
|
||||
msgstr "Establece este ajuste en \"No\" para ocultar todas las publicaciones de citas de tus noticias. Las repeticiones seguirán siendo visibles."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:113
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:119
|
||||
msgid "Set this setting to \"No\" to hide all replies from your feed."
|
||||
msgstr "Establece este ajuste en \"No\" para ocultar todas las respuestas de tus noticias."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:182
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:188
|
||||
msgid "Set this setting to \"No\" to hide all reposts from your feed."
|
||||
msgstr "Establece este ajuste en \"No\" para ocultar todas las veces que se han vuelto a publicar desde tus noticias."
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:116
|
||||
#: src/view/screens/PreferencesThreads.tsx:122
|
||||
msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature."
|
||||
msgstr "Establece este ajuste en \"Sí\" para mostrar las respuestas en una vista de hilos. Se trata de una función experimental."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:252
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:258
|
||||
msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature."
|
||||
msgstr "Establece este ajuste en \"Sí\" para mostrar muestras de tus noticias guardadas en tu siguiente canal de noticias. Se trata de una función experimental."
|
||||
|
||||
@@ -1930,23 +1997,27 @@ msgstr "Mostrar"
|
||||
msgid "Show anyway"
|
||||
msgstr "Mostrar de todas maneras"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:249
|
||||
#: src/view/com/modals/EmbedConsent.tsx:87
|
||||
msgid "Show embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:255
|
||||
msgid "Show Posts from My Feeds"
|
||||
msgstr "Mostrar publicaciones de mis noticias"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:213
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:219
|
||||
msgid "Show Quote Posts"
|
||||
msgstr "Mostrar publicaciones de citas"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:110
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:116
|
||||
msgid "Show Replies"
|
||||
msgstr "Mostrar respuestas"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:94
|
||||
#: src/view/screens/PreferencesThreads.tsx:100
|
||||
msgid "Show replies by people you follow before all other replies."
|
||||
msgstr "Mostrar las respuestas de las personas a quienes sigues antes que el resto de respuestas."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:179
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:185
|
||||
msgid "Show Reposts"
|
||||
msgstr "Mostrar publicaciones que se han publicado nuevamente"
|
||||
|
||||
@@ -1983,7 +2054,7 @@ msgstr "Iniciar sesión como {0}"
|
||||
msgid "Sign in as..."
|
||||
msgstr "Iniciar sesión como ..."
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:130
|
||||
#: src/view/com/auth/login/LoginForm.tsx:134
|
||||
msgid "Sign into"
|
||||
msgstr "Iniciar sesión en"
|
||||
|
||||
@@ -2037,11 +2108,11 @@ msgstr "Cuadrado"
|
||||
msgid "Staging"
|
||||
msgstr "Puesta en escena"
|
||||
|
||||
#: src/view/screens/Settings.tsx:730
|
||||
#: src/view/screens/Settings.tsx:763
|
||||
msgid "Status page"
|
||||
msgstr "Página de estado"
|
||||
|
||||
#: src/view/screens/Settings.tsx:666
|
||||
#: src/view/screens/Settings.tsx:699
|
||||
msgid "Storybook"
|
||||
msgstr "Libro de cuentos"
|
||||
|
||||
@@ -2070,7 +2141,7 @@ msgstr "Soporte"
|
||||
msgid "Switch Account"
|
||||
msgstr "Cambiar a otra cuenta"
|
||||
|
||||
#: src/view/screens/Settings.tsx:646
|
||||
#: src/view/screens/Settings.tsx:679
|
||||
msgid "System log"
|
||||
msgstr "Bitácora del sistema"
|
||||
|
||||
@@ -2082,7 +2153,7 @@ msgstr "Alto"
|
||||
msgid "Terms"
|
||||
msgstr "Condiciones"
|
||||
|
||||
#: src/view/screens/Settings.tsx:744
|
||||
#: src/view/screens/Settings.tsx:777
|
||||
#: src/view/screens/TermsOfService.tsx:29
|
||||
#: src/view/shell/Drawer.tsx:256
|
||||
msgid "Terms of Service"
|
||||
@@ -2125,10 +2196,6 @@ msgstr "Las condiciones de servicio se han trasladado a"
|
||||
msgid "There was an unexpected issue in the application. Please let us know if this happened to you!"
|
||||
msgstr "Se ha producido un problema inesperado en la aplicación. Por favor, ¡avísanos si te ha ocurrido esto!"
|
||||
|
||||
#: src/view/com/util/moderation/LabelInfo.tsx:45
|
||||
#~ msgid "This {0} has been labeled."
|
||||
#~ msgstr "Este {0} ha sido etiquetado."
|
||||
|
||||
#: src/view/com/util/moderation/ScreenHider.tsx:88
|
||||
msgid "This {screenDescription} has been flagged:"
|
||||
msgstr "Esta {screenDescription} ha sido marcada:"
|
||||
@@ -2137,6 +2204,10 @@ msgstr "Esta {screenDescription} ha sido marcada:"
|
||||
msgid "This account has requested that users sign in to view their profile."
|
||||
msgstr "Esta cuenta ha solicitado que los usuarios inicien sesión para ver su perfil."
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:68
|
||||
msgid "This content is hosted by {0}. Do you want to enable external media?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/posts/FeedErrorMessage.tsx:107
|
||||
msgid "This content is not viewable without a Bluesky account."
|
||||
msgstr "Este contenido no se puede ver sin una cuenta Bluesky."
|
||||
@@ -2171,14 +2242,14 @@ msgstr "Esta advertencia sólo está disponible para las publicaciones con medio
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:178
|
||||
msgid "This will hide this post from your feeds."
|
||||
msgstr ""
|
||||
msgstr "Esto ocultará esta entrada de tus contenidos."
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:53
|
||||
#: src/view/screens/Settings.tsx:503
|
||||
msgid "Thread Preferences"
|
||||
msgstr "Preferencias de hilos"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:113
|
||||
#: src/view/screens/PreferencesThreads.tsx:119
|
||||
msgid "Threaded Mode"
|
||||
msgstr "Modo con hilos"
|
||||
|
||||
@@ -2210,7 +2281,7 @@ msgstr "Desactivar la opción de silenciar la lista"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:65
|
||||
#: src/view/com/auth/login/Login.tsx:76
|
||||
#: src/view/com/auth/login/LoginForm.tsx:117
|
||||
#: src/view/com/auth/login/LoginForm.tsx:120
|
||||
msgid "Unable to contact your service. Please check your Internet connection."
|
||||
msgstr "No se puede contactar con tu servicio. Comprueba tu conexión a Internet."
|
||||
|
||||
@@ -2228,7 +2299,7 @@ msgstr "Desbloquear una cuenta"
|
||||
msgid "Undo repost"
|
||||
msgstr "Deshacer esta publicación"
|
||||
|
||||
#: src/view/com/auth/create/state.ts:210
|
||||
#: src/view/com/auth/create/state.ts:216
|
||||
msgid "Unfortunately, you do not meet the requirements to create an account."
|
||||
msgstr "Lamentablemente, no cumples los requisitos para crear una cuenta."
|
||||
|
||||
@@ -2284,8 +2355,8 @@ msgstr "Identificador del usuario"
|
||||
msgid "User Lists"
|
||||
msgstr "Listas de usuarios"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:170
|
||||
#: src/view/com/auth/login/LoginForm.tsx:188
|
||||
#: src/view/com/auth/login/LoginForm.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:192
|
||||
msgid "Username or email address"
|
||||
msgstr "Nombre de usuario o dirección de correo electrónico"
|
||||
|
||||
@@ -2301,15 +2372,15 @@ msgstr "usuarios seguidos por <0/>"
|
||||
msgid "Users in \"{0}\""
|
||||
msgstr "Usuarios en «{0}»"
|
||||
|
||||
#: src/view/screens/Settings.tsx:769
|
||||
#: src/view/screens/Settings.tsx:802
|
||||
msgid "Verify email"
|
||||
msgstr "Verificar el correo electrónico"
|
||||
|
||||
#: src/view/screens/Settings.tsx:794
|
||||
#: src/view/screens/Settings.tsx:827
|
||||
msgid "Verify my email"
|
||||
msgstr "Verificar mi correo electrónico"
|
||||
|
||||
#: src/view/screens/Settings.tsx:803
|
||||
#: src/view/screens/Settings.tsx:836
|
||||
msgid "Verify My Email"
|
||||
msgstr "Verificar mi correo electrónico"
|
||||
|
||||
@@ -2350,13 +2421,9 @@ msgstr "Bienvenido a <0>Bluesky</0>"
|
||||
msgid "What is the issue with this {collectionName}?"
|
||||
msgstr "¿Cuál es el problema con esta {collectionName}?"
|
||||
|
||||
#: src/view/com/auth/SplashScreen.tsx:34
|
||||
#~ msgid "What's next?"
|
||||
#~ msgstr "¿Qué sigue?"
|
||||
|
||||
#: src/view/com/auth/SplashScreen.tsx:34
|
||||
msgid "What's up?"
|
||||
msgstr ""
|
||||
msgstr "¿Qué hay de nuevo?"
|
||||
|
||||
#: src/view/com/modals/lang-settings/PostLanguagesSettings.tsx:78
|
||||
msgid "Which languages are used in this post?"
|
||||
@@ -2375,7 +2442,7 @@ msgstr "Quién puede responder"
|
||||
msgid "Wide"
|
||||
msgstr "Ancho"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:413
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
msgid "Write post"
|
||||
msgstr "Redactar una publicación"
|
||||
|
||||
@@ -2383,10 +2450,12 @@ msgstr "Redactar una publicación"
|
||||
msgid "Write your reply"
|
||||
msgstr "Redactar tu respuesta"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:192
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:227
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:262
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:198
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:233
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:268
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "Yes"
|
||||
msgstr "Sí"
|
||||
|
||||
|
||||
+300
-222
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,7 @@ msgstr "ऐप का एक नया संस्करण उपलब्ध
|
||||
msgid "Accessibility"
|
||||
msgstr "प्रवेर्शयोग्यता"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:159
|
||||
#: src/view/com/auth/login/LoginForm.tsx:163
|
||||
#: src/view/screens/Settings.tsx:286
|
||||
msgid "Account"
|
||||
msgstr "अकाउंट"
|
||||
@@ -118,6 +118,7 @@ msgstr "अकाउंट जोड़ें"
|
||||
|
||||
#: src/view/com/composer/photos/Gallery.tsx:119
|
||||
#: src/view/com/composer/photos/Gallery.tsx:180
|
||||
#: src/view/com/modals/AltImage.tsx:93
|
||||
msgid "Add alt text"
|
||||
msgstr "इस फ़ोटो में विवरण जोड़ें"
|
||||
|
||||
@@ -130,11 +131,11 @@ msgstr "विवरण जोड़ें"
|
||||
msgid "Add details to report"
|
||||
msgstr "रिपोर्ट करने के लिए विवरण जोड़ें"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:442
|
||||
#: src/view/com/composer/Composer.tsx:447
|
||||
msgid "Add link card"
|
||||
msgstr "लिंक कार्ड जोड़ें"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:445
|
||||
#: src/view/com/composer/Composer.tsx:450
|
||||
msgid "Add link card:"
|
||||
msgstr "लिंक कार्ड जोड़ें:"
|
||||
|
||||
@@ -155,7 +156,7 @@ msgstr "इस फ़ीड को सहेजें"
|
||||
msgid "Added to list"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:164
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:170
|
||||
msgid "Adjust the number of likes a reply must have to be shown in your feed."
|
||||
msgstr "पसंद की संख्या को समायोजित करें उत्तर को आपके फ़ीड में दिखाया जाना चाहिए।।"
|
||||
|
||||
@@ -163,7 +164,7 @@ msgstr "पसंद की संख्या को समायोजित
|
||||
msgid "Adult Content"
|
||||
msgstr "वयस्क सामग्री"
|
||||
|
||||
#: src/view/screens/Settings.tsx:569
|
||||
#: src/view/screens/Settings.tsx:602
|
||||
msgid "Advanced"
|
||||
msgstr "विकसित"
|
||||
|
||||
@@ -196,7 +197,7 @@ msgstr "और"
|
||||
msgid "App Language"
|
||||
msgstr "ऐप भाषा"
|
||||
|
||||
#: src/view/screens/Settings.tsx:589
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
msgid "App passwords"
|
||||
msgstr "ऐप पासवर्ड"
|
||||
|
||||
@@ -236,7 +237,7 @@ msgstr "दिखावट"
|
||||
msgid "Are you sure you want to delete the app password \"{name}\"?"
|
||||
msgstr "क्या आप वाकई ऐप पासवर्ड \"{name}\" हटाना चाहते हैं?"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:142
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr "क्या आप वाकई इस ड्राफ्ट को हटाना करना चाहेंगे?"
|
||||
|
||||
@@ -259,7 +260,7 @@ msgstr "कलात्मक या गैर-कामुक नग्नत
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:141
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:151
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:166
|
||||
#: src/view/com/auth/login/LoginForm.tsx:250
|
||||
#: src/view/com/auth/login/LoginForm.tsx:254
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:148
|
||||
#: src/view/com/modals/report/InputIssueDetails.tsx:46
|
||||
#: src/view/com/post-thread/PostThread.tsx:388
|
||||
@@ -355,7 +356,7 @@ msgstr ""
|
||||
msgid "Bluesky.Social"
|
||||
msgstr "Bluesky.Social"
|
||||
|
||||
#: src/view/screens/Settings.tsx:718
|
||||
#: src/view/screens/Settings.tsx:751
|
||||
msgid "Build version {0} {1}"
|
||||
msgstr "Build version {0} {1}"
|
||||
|
||||
@@ -373,9 +374,8 @@ msgstr "कैमरा"
|
||||
msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long."
|
||||
msgstr "केवल अक्षर, संख्या, रिक्त स्थान, डैश और अंडरस्कोर हो सकते हैं। कम से कम 4 अक्षर लंबा होना चाहिए, लेकिन 32 अक्षरों से अधिक लंबा नहीं होना चाहिए।।"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:289
|
||||
#: src/view/com/composer/Composer.tsx:292
|
||||
#: src/view/com/modals/AltImage.tsx:128
|
||||
#: src/view/com/composer/Composer.tsx:294
|
||||
#: src/view/com/composer/Composer.tsx:297
|
||||
#: src/view/com/modals/ChangeEmail.tsx:218
|
||||
#: src/view/com/modals/ChangeEmail.tsx:220
|
||||
#: src/view/com/modals/Confirm.tsx:88
|
||||
@@ -399,8 +399,8 @@ msgid "Cancel account deletion"
|
||||
msgstr "अकाउंट बंद मत करो"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:123
|
||||
msgid "Cancel add image alt text"
|
||||
msgstr "ऑल्ट टेक्स्ट मत जोड़ें"
|
||||
#~ msgid "Cancel add image alt text"
|
||||
#~ msgstr "ऑल्ट टेक्स्ट मत जोड़ें"
|
||||
|
||||
#: src/view/com/modals/ChangeHandle.tsx:149
|
||||
msgid "Cancel change handle"
|
||||
@@ -431,8 +431,8 @@ msgstr "प्रतीक्षा सूची पंजीकरण मत
|
||||
msgid "Change"
|
||||
msgstr "परिवर्तन"
|
||||
|
||||
#: src/view/screens/Settings.tsx:601
|
||||
#: src/view/screens/Settings.tsx:610
|
||||
#: src/view/screens/Settings.tsx:634
|
||||
#: src/view/screens/Settings.tsx:643
|
||||
msgid "Change handle"
|
||||
msgstr "हैंडल बदलें"
|
||||
|
||||
@@ -476,19 +476,19 @@ msgstr "उन एल्गोरिदम का चयन करें जो
|
||||
msgid "Choose your password"
|
||||
msgstr "अपना पासवर्ड चुनें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:694
|
||||
#: src/view/screens/Settings.tsx:727
|
||||
msgid "Clear all legacy storage data"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:696
|
||||
#: src/view/screens/Settings.tsx:729
|
||||
msgid "Clear all legacy storage data (restart after this)"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:706
|
||||
#: src/view/screens/Settings.tsx:739
|
||||
msgid "Clear all storage data"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:708
|
||||
#: src/view/screens/Settings.tsx:741
|
||||
msgid "Clear all storage data (restart after this)"
|
||||
msgstr ""
|
||||
|
||||
@@ -529,8 +529,8 @@ msgstr "जवाब लिखो"
|
||||
#: src/view/com/modals/Confirm.tsx:75
|
||||
#: src/view/com/modals/SelfLabel.tsx:154
|
||||
#: src/view/com/modals/VerifyEmail.tsx:225
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:299
|
||||
#: src/view/screens/PreferencesThreads.tsx:153
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:305
|
||||
#: src/view/screens/PreferencesThreads.tsx:159
|
||||
msgid "Confirm"
|
||||
msgstr "हो गया"
|
||||
|
||||
@@ -554,7 +554,7 @@ msgid "Confirmation code"
|
||||
msgstr "OTP कोड"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:269
|
||||
#: src/view/com/auth/login/LoginForm.tsx:273
|
||||
msgid "Connecting..."
|
||||
msgstr "कनेक्टिंग ..।"
|
||||
|
||||
@@ -644,7 +644,11 @@ msgstr "बनाया गया {0}"
|
||||
msgid "Custom domain"
|
||||
msgstr "कस्टम डोमेन"
|
||||
|
||||
#: src/view/screens/Settings.tsx:615
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:55
|
||||
msgid "Customize media from external sites."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:648
|
||||
msgid "Danger Zone"
|
||||
msgstr "खतरा क्षेत्र"
|
||||
|
||||
@@ -652,7 +656,7 @@ msgstr "खतरा क्षेत्र"
|
||||
#~ msgid "Dark"
|
||||
#~ msgstr "डार्क मोड"
|
||||
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
#: src/view/screens/Settings.tsx:655
|
||||
msgid "Delete account"
|
||||
msgstr "खाता हटाएं"
|
||||
|
||||
@@ -674,7 +678,7 @@ msgstr "सूची हटाएँ"
|
||||
msgid "Delete my account"
|
||||
msgstr "मेरा खाता हटाएं"
|
||||
|
||||
#: src/view/screens/Settings.tsx:632
|
||||
#: src/view/screens/Settings.tsx:665
|
||||
msgid "Delete my account…"
|
||||
msgstr "मेरा खाता हटाएं…"
|
||||
|
||||
@@ -701,19 +705,19 @@ msgstr "विवरण"
|
||||
msgid "Dev Server"
|
||||
msgstr "देव सर्वर"
|
||||
|
||||
#: src/view/screens/Settings.tsx:637
|
||||
#: src/view/screens/Settings.tsx:670
|
||||
msgid "Developer Tools"
|
||||
msgstr "डेवलपर उपकरण"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:210
|
||||
#: src/view/com/composer/Composer.tsx:211
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
#: src/view/com/composer/Composer.tsx:144
|
||||
msgid "Discard"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:137
|
||||
#: src/view/com/composer/Composer.tsx:138
|
||||
msgid "Discard draft"
|
||||
msgstr "ड्राफ्ट हटाएं"
|
||||
|
||||
@@ -738,6 +742,7 @@ msgid "Domain verified!"
|
||||
msgstr "डोमेन सत्यापित!"
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:88
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:96
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:152
|
||||
@@ -747,8 +752,8 @@ msgstr "डोमेन सत्यापित!"
|
||||
#: src/view/com/modals/Threadgate.tsx:129
|
||||
#: src/view/com/modals/Threadgate.tsx:132
|
||||
#: src/view/com/modals/UserAddRemoveLists.tsx:79
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:302
|
||||
#: src/view/screens/PreferencesThreads.tsx:156
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:308
|
||||
#: src/view/screens/PreferencesThreads.tsx:162
|
||||
msgid "Done"
|
||||
msgstr "खत्म"
|
||||
|
||||
@@ -809,7 +814,15 @@ msgstr "ईमेल अपडेट किया गया"
|
||||
msgid "Email:"
|
||||
msgstr "ईमेल:"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:138
|
||||
#: src/view/com/modals/EmbedConsent.tsx:113
|
||||
msgid "Enable {0} only"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:97
|
||||
msgid "Enable External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:144
|
||||
msgid "Enable this setting to only see replies between people you follow."
|
||||
msgstr "इस सेटिंग को केवल उन लोगों के बीच जवाब देखने में सक्षम करें जिन्हें आप फॉलो करते हैं।।"
|
||||
|
||||
@@ -853,6 +866,20 @@ msgstr ""
|
||||
msgid "Expand alt text"
|
||||
msgstr "ऑल्ट टेक्स्ट"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:64
|
||||
msgid "External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:75
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:66
|
||||
msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:52
|
||||
#: src/view/screens/Settings.tsx:595
|
||||
msgid "External Media Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141
|
||||
msgid "Failed to load recommended feeds"
|
||||
@@ -900,7 +927,7 @@ msgstr ""
|
||||
msgid "Finding similar accounts..."
|
||||
msgstr "मिलते-जुलते खाते ढूँढना"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:102
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:108
|
||||
msgid "Fine-tune the content you see on your home screen."
|
||||
msgstr "अपने मुख्य फ़ीड की स्क्रीन पर दिखाई देने वाली सामग्री को ठीक करें।।"
|
||||
|
||||
@@ -920,7 +947,7 @@ msgstr "आरंभ करने के लिए कुछ उपयोगक
|
||||
msgid "Followed users"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:145
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:151
|
||||
msgid "Followed users only"
|
||||
msgstr "केवल वे यूजर को फ़ॉलो किया गया"
|
||||
|
||||
@@ -949,11 +976,11 @@ msgstr "सुरक्षा कारणों के लिए, हमें
|
||||
msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one."
|
||||
msgstr "सुरक्षा कारणों के लिए, आप इसे फिर से देखने में सक्षम नहीं होंगे। यदि आप इस पासवर्ड को खो देते हैं, तो आपको एक नया उत्पन्न करना होगा।।"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:232
|
||||
#: src/view/com/auth/login/LoginForm.tsx:236
|
||||
msgid "Forgot"
|
||||
msgstr "भूल"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:229
|
||||
#: src/view/com/auth/login/LoginForm.tsx:233
|
||||
msgid "Forgot password"
|
||||
msgstr "पासवर्ड भूल गए"
|
||||
|
||||
@@ -985,7 +1012,7 @@ msgid "Go Back"
|
||||
msgstr "वापस जाओ"
|
||||
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:181
|
||||
#: src/view/com/auth/login/LoginForm.tsx:279
|
||||
#: src/view/com/auth/login/LoginForm.tsx:283
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:163
|
||||
msgid "Go to next"
|
||||
msgstr "अगला"
|
||||
@@ -1056,7 +1083,7 @@ msgid "Home"
|
||||
msgstr "होम फीड"
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:96
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:95
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:101
|
||||
#: src/view/screens/Settings.tsx:481
|
||||
msgid "Home Feed Preferences"
|
||||
msgstr "होम फ़ीड प्राथमिकताएं"
|
||||
@@ -1096,7 +1123,7 @@ msgstr "छवि विकल्प"
|
||||
#~ msgid "In Your Network"
|
||||
#~ msgstr "आपके नेटवर्क में"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:113
|
||||
#: src/view/com/auth/login/LoginForm.tsx:115
|
||||
msgid "Invalid username or password"
|
||||
msgstr "अवैध उपयोगकर्ता नाम या पासवर्ड"
|
||||
|
||||
@@ -1321,6 +1348,10 @@ msgstr "अधिक विकल्प"
|
||||
#~ msgid "More post options"
|
||||
#~ msgstr "पोस्ट विकल्प"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:82
|
||||
msgid "Most-liked replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/profile/ProfileHeader.tsx:370
|
||||
msgid "Mute Account"
|
||||
msgstr "खाता म्यूट करें"
|
||||
@@ -1382,6 +1413,11 @@ msgstr "मेरी फ़ीड"
|
||||
msgid "Name"
|
||||
msgstr "नाम"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:107
|
||||
#: src/view/com/modals/EmbedConsent.tsx:123
|
||||
msgid "Never load embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72
|
||||
msgid "Never lose access to your followers and data."
|
||||
msgstr "अपने फ़ॉलोअर्स और डेटा तक पहुंच कभी न खोएं।"
|
||||
@@ -1405,10 +1441,14 @@ msgstr "नई पोस्ट"
|
||||
msgid "New Post"
|
||||
msgstr "नई पोस्ट"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:79
|
||||
msgid "Newest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:154
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:174
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:184
|
||||
#: src/view/com/auth/login/LoginForm.tsx:282
|
||||
#: src/view/com/auth/login/LoginForm.tsx:286
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:156
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:166
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79
|
||||
@@ -1419,10 +1459,12 @@ msgstr "अगला"
|
||||
msgid "Next image"
|
||||
msgstr "अगली फोटो"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:191
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:226
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:263
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:197
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:232
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:269
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "No"
|
||||
msgstr "नहीं"
|
||||
|
||||
@@ -1452,6 +1494,10 @@ msgstr "\"{query}\" के लिए कोई परिणाम नहीं
|
||||
msgid "No results found for {query}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:129
|
||||
msgid "No thanks"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:82
|
||||
msgid "Nobody"
|
||||
msgstr ""
|
||||
@@ -1493,7 +1539,11 @@ msgstr "अरे नहीं!"
|
||||
msgid "Okay"
|
||||
msgstr "ठीक है"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:358
|
||||
#: src/view/screens/PreferencesThreads.tsx:78
|
||||
msgid "Oldest replies first"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:363
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr "एक या अधिक छवियाँ alt पाठ याद आती हैं।।"
|
||||
|
||||
@@ -1501,6 +1551,11 @@ msgstr "एक या अधिक छवियाँ alt पाठ याद
|
||||
msgid "Only {0} can reply."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
#: src/view/com/composer/Composer.tsx:469
|
||||
msgid "Open emoji picker"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:76
|
||||
msgid "Open navigation"
|
||||
msgstr "ओपन नेविगेशन"
|
||||
@@ -1509,6 +1564,10 @@ msgstr "ओपन नेविगेशन"
|
||||
msgid "Opens configurable language settings"
|
||||
msgstr "भाषा सेटिंग्स खोलें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:587
|
||||
msgid "Opens external embeds settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:156
|
||||
#: src/view/shell/Drawer.tsx:641
|
||||
msgid "Opens list of invite codes"
|
||||
@@ -1526,7 +1585,7 @@ msgstr "मॉडरेशन सेटिंग्स खोलें"
|
||||
msgid "Opens screen with all saved feeds"
|
||||
msgstr "सभी बचाया फ़ीड के साथ स्क्रीन खोलें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:581
|
||||
#: src/view/screens/Settings.tsx:614
|
||||
msgid "Opens the app password settings page"
|
||||
msgstr "ऐप पासवर्ड सेटिंग पेज खोलें"
|
||||
|
||||
@@ -1534,11 +1593,11 @@ msgstr "ऐप पासवर्ड सेटिंग पेज खोले
|
||||
msgid "Opens the home feed preferences"
|
||||
msgstr "होम फीड वरीयताओं को खोलता है"
|
||||
|
||||
#: src/view/screens/Settings.tsx:664
|
||||
#: src/view/screens/Settings.tsx:697
|
||||
msgid "Opens the storybook page"
|
||||
msgstr "स्टोरीबुक पेज खोलें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:644
|
||||
#: src/view/screens/Settings.tsx:677
|
||||
msgid "Opens the system log page"
|
||||
msgstr "सिस्टम लॉग पेज खोलें"
|
||||
|
||||
@@ -1569,7 +1628,7 @@ msgstr "पृष्ठ नहीं मिला"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:122
|
||||
#: src/view/com/auth/create/Step2.tsx:132
|
||||
#: src/view/com/auth/login/LoginForm.tsx:217
|
||||
#: src/view/com/auth/login/LoginForm.tsx:221
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:130
|
||||
#: src/view/com/modals/DeleteAccount.tsx:191
|
||||
msgid "Password"
|
||||
@@ -1591,6 +1650,19 @@ msgstr "चित्र वयस्कों के लिए थे।।"
|
||||
msgid "Pinned Feeds"
|
||||
msgstr "पिन किया गया फ़ीड"
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111
|
||||
msgid "Play {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55
|
||||
msgid "Play Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110
|
||||
msgid "Plays the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:116
|
||||
msgid "Please choose your handle."
|
||||
msgstr ""
|
||||
@@ -1625,11 +1697,11 @@ msgstr ""
|
||||
#~ msgid "Please tell us why you think this decision was incorrect."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:214
|
||||
#: src/view/com/composer/Composer.tsx:215
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:341
|
||||
#: src/view/com/composer/Composer.tsx:346
|
||||
#: src/view/com/post-thread/PostThread.tsx:225
|
||||
#: src/view/screens/PostThread.tsx:80
|
||||
msgid "Post"
|
||||
@@ -1667,16 +1739,17 @@ msgstr "पिछली छवि"
|
||||
msgid "Primary Language"
|
||||
msgstr "प्राथमिक भाषा"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:91
|
||||
#: src/view/screens/PreferencesThreads.tsx:97
|
||||
msgid "Prioritize Your Follows"
|
||||
msgstr "अपने फ़ॉलोअर्स को प्राथमिकता दें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:570
|
||||
#: src/view/shell/desktop/RightNav.tsx:84
|
||||
msgid "Privacy"
|
||||
msgstr "गोपनीयता"
|
||||
|
||||
#: src/view/screens/PrivacyPolicy.tsx:29
|
||||
#: src/view/screens/Settings.tsx:750
|
||||
#: src/view/screens/Settings.tsx:783
|
||||
#: src/view/shell/Drawer.tsx:262
|
||||
msgid "Privacy Policy"
|
||||
msgstr "गोपनीयता नीति"
|
||||
@@ -1693,7 +1766,7 @@ msgstr "प्रसंस्करण..."
|
||||
msgid "Profile"
|
||||
msgstr "प्रोफ़ाइल"
|
||||
|
||||
#: src/view/screens/Settings.tsx:808
|
||||
#: src/view/screens/Settings.tsx:841
|
||||
msgid "Protect your account by verifying your email."
|
||||
msgstr "अपने ईमेल को सत्यापित करके अपने खाते को सुरक्षित रखें।।"
|
||||
|
||||
@@ -1714,6 +1787,10 @@ msgstr "कोटे पोस्ट"
|
||||
msgid "Quote Post"
|
||||
msgstr "कोटे पोस्ट"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:86
|
||||
msgid "Random (aka \"Poster's Roulette\")"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EditImage.tsx:236
|
||||
msgid "Ratios"
|
||||
msgstr "अनुपात"
|
||||
@@ -1786,7 +1863,7 @@ msgstr ""
|
||||
msgid "Replies to this thread are disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:135
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:141
|
||||
msgid "Reply Filters"
|
||||
msgstr "फिल्टर"
|
||||
|
||||
@@ -1833,9 +1910,9 @@ msgstr "अनुरोध बदलें"
|
||||
#~ msgid "Request to limit the visibility of my account"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:382
|
||||
#~ msgid "Require alt text before posting"
|
||||
#~ msgstr "पोस्ट करने से पहले वैकल्पिक टेक्स्ट की आवश्यकता है"
|
||||
#: src/view/screens/Settings.tsx:422
|
||||
msgid "Require alt text before posting"
|
||||
msgstr "पोस्ट करने से पहले वैकल्पिक टेक्स्ट की आवश्यकता है"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:68
|
||||
msgid "Required for this provider"
|
||||
@@ -1845,7 +1922,7 @@ msgstr "इस प्रदाता के लिए आवश्यक"
|
||||
msgid "Reset code"
|
||||
msgstr "कोड रीसेट करें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:686
|
||||
#: src/view/screens/Settings.tsx:719
|
||||
msgid "Reset onboarding state"
|
||||
msgstr "ऑनबोर्डिंग स्टेट को रीसेट करें"
|
||||
|
||||
@@ -1853,22 +1930,22 @@ msgstr "ऑनबोर्डिंग स्टेट को रीसेट
|
||||
msgid "Reset password"
|
||||
msgstr "पासवर्ड रीसेट"
|
||||
|
||||
#: src/view/screens/Settings.tsx:676
|
||||
#: src/view/screens/Settings.tsx:709
|
||||
msgid "Reset preferences state"
|
||||
msgstr "प्राथमिकताओं को रीसेट करें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:684
|
||||
#: src/view/screens/Settings.tsx:717
|
||||
msgid "Resets the onboarding state"
|
||||
msgstr "ऑनबोर्डिंग स्टेट को रीसेट करें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:674
|
||||
#: src/view/screens/Settings.tsx:707
|
||||
msgid "Resets the preferences state"
|
||||
msgstr "प्राथमिकताओं की स्थिति को रीसेट करें"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:163
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:167
|
||||
#: src/view/com/auth/login/LoginForm.tsx:259
|
||||
#: src/view/com/auth/login/LoginForm.tsx:262
|
||||
#: src/view/com/auth/login/LoginForm.tsx:263
|
||||
#: src/view/com/auth/login/LoginForm.tsx:266
|
||||
#: src/view/com/util/error/ErrorMessage.tsx:55
|
||||
#: src/view/com/util/error/ErrorScreen.tsx:65
|
||||
msgid "Retry"
|
||||
@@ -1878,7 +1955,6 @@ msgstr "फिर से कोशिश करो"
|
||||
#~ msgid "Retry change handle"
|
||||
#~ msgstr "हैंडल बदलना फिर से कोशिश करो"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:94
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:97
|
||||
#: src/view/com/modals/ChangeHandle.tsx:173
|
||||
@@ -1950,7 +2026,7 @@ msgstr "Bluesky Social का चयन करें"
|
||||
msgid "Select from an existing account"
|
||||
msgstr "मौजूदा खाते से चुनें"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:143
|
||||
#: src/view/com/auth/login/LoginForm.tsx:147
|
||||
msgid "Select service"
|
||||
msgstr "सेवा चुनें"
|
||||
|
||||
@@ -1991,23 +2067,23 @@ msgstr "रिपोर्ट भेजें"
|
||||
msgid "Set new password"
|
||||
msgstr "नया पासवर्ड सेट करें"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:216
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:222
|
||||
msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible."
|
||||
msgstr "अपने फ़ीड से सभी उद्धरण पदों को छिपाने के लिए इस सेटिंग को \"नहीं\" में सेट करें। Reposts अभी भी दिखाई देगा।।"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:113
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:119
|
||||
msgid "Set this setting to \"No\" to hide all replies from your feed."
|
||||
msgstr "इस सेटिंग को अपने फ़ीड से सभी उत्तरों को छिपाने के लिए \"नहीं\" पर सेट करें।।"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:182
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:188
|
||||
msgid "Set this setting to \"No\" to hide all reposts from your feed."
|
||||
msgstr "इस सेटिंग को अपने फ़ीड से सभी पोस्ट छिपाने के लिए \"नहीं\" करने के लिए सेट करें।।"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:116
|
||||
#: src/view/screens/PreferencesThreads.tsx:122
|
||||
msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature."
|
||||
msgstr "इस सेटिंग को \"हाँ\" में सेट करने के लिए एक थ्रेडेड व्यू में जवाब दिखाने के लिए। यह एक प्रयोगात्मक विशेषता है।।"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:252
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:258
|
||||
msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature."
|
||||
msgstr "इस सेटिंग को अपने निम्नलिखित फ़ीड में अपने सहेजे गए फ़ीड के नमूने दिखाने के लिए \"हाँ\" पर सेट करें। यह एक प्रयोगात्मक विशेषता है।।"
|
||||
|
||||
@@ -2045,23 +2121,27 @@ msgstr "दिखाओ"
|
||||
msgid "Show anyway"
|
||||
msgstr "दिखाओ"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:249
|
||||
#: src/view/com/modals/EmbedConsent.tsx:87
|
||||
msgid "Show embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:255
|
||||
msgid "Show Posts from My Feeds"
|
||||
msgstr "मेरी फीड से पोस्ट दिखाएं"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:213
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:219
|
||||
msgid "Show Quote Posts"
|
||||
msgstr "उद्धरण पोस्ट दिखाओ"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:110
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:116
|
||||
msgid "Show Replies"
|
||||
msgstr "उत्तर दिखाएँ"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:94
|
||||
#: src/view/screens/PreferencesThreads.tsx:100
|
||||
msgid "Show replies by people you follow before all other replies."
|
||||
msgstr "अन्य सभी उत्तरों से पहले उन लोगों के उत्तर दिखाएं जिन्हें आप फ़ॉलो करते हैं।"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:179
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:185
|
||||
msgid "Show Reposts"
|
||||
msgstr "रीपोस्ट दिखाएँ"
|
||||
|
||||
@@ -2098,7 +2178,7 @@ msgstr "{0} के रूप में साइन इन करें"
|
||||
msgid "Sign in as..."
|
||||
msgstr "... के रूप में साइन इन करें"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:130
|
||||
#: src/view/com/auth/login/LoginForm.tsx:134
|
||||
msgid "Sign into"
|
||||
msgstr "साइन इन करें"
|
||||
|
||||
@@ -2152,11 +2232,11 @@ msgstr "स्क्वायर"
|
||||
msgid "Staging"
|
||||
msgstr "स्टेजिंग"
|
||||
|
||||
#: src/view/screens/Settings.tsx:730
|
||||
#: src/view/screens/Settings.tsx:763
|
||||
msgid "Status page"
|
||||
msgstr "स्थिति पृष्ठ"
|
||||
|
||||
#: src/view/screens/Settings.tsx:666
|
||||
#: src/view/screens/Settings.tsx:699
|
||||
msgid "Storybook"
|
||||
msgstr "Storybook"
|
||||
|
||||
@@ -2189,7 +2269,7 @@ msgstr "खाते बदलें"
|
||||
#~ msgid "System"
|
||||
#~ msgstr "प्रणाली"
|
||||
|
||||
#: src/view/screens/Settings.tsx:646
|
||||
#: src/view/screens/Settings.tsx:679
|
||||
msgid "System log"
|
||||
msgstr "सिस्टम लॉग"
|
||||
|
||||
@@ -2201,7 +2281,7 @@ msgstr "लंबा"
|
||||
msgid "Terms"
|
||||
msgstr "शर्तें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:744
|
||||
#: src/view/screens/Settings.tsx:777
|
||||
#: src/view/screens/TermsOfService.tsx:29
|
||||
#: src/view/shell/Drawer.tsx:256
|
||||
msgid "Terms of Service"
|
||||
@@ -2256,6 +2336,10 @@ msgstr "यह {screenDescription} फ्लैग किया गया है
|
||||
msgid "This account has requested that users sign in to view their profile."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:68
|
||||
msgid "This content is hosted by {0}. Do you want to enable external media?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/posts/FeedErrorMessage.tsx:107
|
||||
msgid "This content is not viewable without a Bluesky account."
|
||||
msgstr ""
|
||||
@@ -2297,7 +2381,7 @@ msgstr ""
|
||||
msgid "Thread Preferences"
|
||||
msgstr "थ्रेड प्राथमिकता"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:113
|
||||
#: src/view/screens/PreferencesThreads.tsx:119
|
||||
msgid "Threaded Mode"
|
||||
msgstr "थ्रेड मोड"
|
||||
|
||||
@@ -2329,7 +2413,7 @@ msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:65
|
||||
#: src/view/com/auth/login/Login.tsx:76
|
||||
#: src/view/com/auth/login/LoginForm.tsx:117
|
||||
#: src/view/com/auth/login/LoginForm.tsx:120
|
||||
msgid "Unable to contact your service. Please check your Internet connection."
|
||||
msgstr "आपकी सेवा से संपर्क करने में असमर्थ। कृपया अपने इंटरनेट कनेक्शन की जांच करें।।"
|
||||
|
||||
@@ -2347,7 +2431,7 @@ msgstr "अनब्लॉक खाता"
|
||||
msgid "Undo repost"
|
||||
msgstr "पुनः पोस्ट पूर्ववत करें"
|
||||
|
||||
#: src/view/com/auth/create/state.ts:210
|
||||
#: src/view/com/auth/create/state.ts:216
|
||||
msgid "Unfortunately, you do not meet the requirements to create an account."
|
||||
msgstr ""
|
||||
|
||||
@@ -2403,8 +2487,8 @@ msgstr "यूजर हैंडल"
|
||||
msgid "User Lists"
|
||||
msgstr "लोग सूचियाँ"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:170
|
||||
#: src/view/com/auth/login/LoginForm.tsx:188
|
||||
#: src/view/com/auth/login/LoginForm.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:192
|
||||
msgid "Username or email address"
|
||||
msgstr "यूजर नाम या ईमेल पता"
|
||||
|
||||
@@ -2424,15 +2508,15 @@ msgstr ""
|
||||
msgid "Users in \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:769
|
||||
#: src/view/screens/Settings.tsx:802
|
||||
msgid "Verify email"
|
||||
msgstr "ईमेल सत्यापित करें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:794
|
||||
#: src/view/screens/Settings.tsx:827
|
||||
msgid "Verify my email"
|
||||
msgstr "मेरी ईमेल सत्यापित करें"
|
||||
|
||||
#: src/view/screens/Settings.tsx:803
|
||||
#: src/view/screens/Settings.tsx:836
|
||||
msgid "Verify My Email"
|
||||
msgstr "मेरी ईमेल सत्यापित करें"
|
||||
|
||||
@@ -2506,7 +2590,7 @@ msgstr ""
|
||||
msgid "Wide"
|
||||
msgstr "चौड़ा"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:413
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
msgid "Write post"
|
||||
msgstr "पोस्ट लिखो"
|
||||
|
||||
@@ -2514,10 +2598,12 @@ msgstr "पोस्ट लिखो"
|
||||
msgid "Write your reply"
|
||||
msgstr "अपना जवाब दें"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:192
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:227
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:262
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:198
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:233
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:268
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "Yes"
|
||||
msgstr "हाँ"
|
||||
|
||||
|
||||
+192
-102
@@ -5,7 +5,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: jp\n"
|
||||
"Language: ja\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
@@ -68,7 +68,7 @@ msgstr "新しいバージョンのアプリが利用可能です。継続して
|
||||
msgid "Accessibility"
|
||||
msgstr "アクセシビリティ"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:159
|
||||
#: src/view/com/auth/login/LoginForm.tsx:163
|
||||
#: src/view/screens/Settings.tsx:286
|
||||
msgid "Account"
|
||||
msgstr "アカウント"
|
||||
@@ -98,6 +98,7 @@ msgstr "アカウントを追加"
|
||||
|
||||
#: src/view/com/composer/photos/Gallery.tsx:119
|
||||
#: src/view/com/composer/photos/Gallery.tsx:180
|
||||
#: src/view/com/modals/AltImage.tsx:93
|
||||
msgid "Add alt text"
|
||||
msgstr "ALTテキストを追加"
|
||||
|
||||
@@ -110,11 +111,11 @@ msgstr "詳細を追加"
|
||||
msgid "Add details to report"
|
||||
msgstr "レポートに詳細を追加"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:442
|
||||
#: src/view/com/composer/Composer.tsx:447
|
||||
msgid "Add link card"
|
||||
msgstr "リンクカードを追加"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:445
|
||||
#: src/view/com/composer/Composer.tsx:450
|
||||
msgid "Add link card:"
|
||||
msgstr "リンクカードを追加:"
|
||||
|
||||
@@ -135,7 +136,7 @@ msgstr "マイフィードに追加"
|
||||
msgid "Added to list"
|
||||
msgstr "リストに追加"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:164
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:170
|
||||
msgid "Adjust the number of likes a reply must have to be shown in your feed."
|
||||
msgstr "返信がフィードに表示されるために必要な「いいね」の数を調整します。"
|
||||
|
||||
@@ -143,7 +144,7 @@ msgstr "返信がフィードに表示されるために必要な「いいね」
|
||||
msgid "Adult Content"
|
||||
msgstr "成人向けコンテンツ"
|
||||
|
||||
#: src/view/screens/Settings.tsx:569
|
||||
#: src/view/screens/Settings.tsx:602
|
||||
msgid "Advanced"
|
||||
msgstr "高度な設定"
|
||||
|
||||
@@ -176,7 +177,7 @@ msgstr "および"
|
||||
msgid "App Language"
|
||||
msgstr "アプリの言語"
|
||||
|
||||
#: src/view/screens/Settings.tsx:589
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
msgid "App passwords"
|
||||
msgstr "アプリパスワード"
|
||||
|
||||
@@ -212,7 +213,7 @@ msgstr "外観"
|
||||
msgid "Are you sure you want to delete the app password \"{name}\"?"
|
||||
msgstr "本当にアプリパスワード「{name}」を削除しますか?"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:142
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr "本当にこの下書きを破棄しますか?"
|
||||
|
||||
@@ -231,7 +232,7 @@ msgstr "芸術的または性的ではないヌード。"
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:141
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:151
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:166
|
||||
#: src/view/com/auth/login/LoginForm.tsx:250
|
||||
#: src/view/com/auth/login/LoginForm.tsx:254
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:148
|
||||
#: src/view/com/modals/report/InputIssueDetails.tsx:46
|
||||
#: src/view/com/post-thread/PostThread.tsx:388
|
||||
@@ -327,7 +328,7 @@ msgstr "Blueskyはログアウトしたユーザーにあなたのプロフィ
|
||||
msgid "Bluesky.Social"
|
||||
msgstr "Bluesky.Social"
|
||||
|
||||
#: src/view/screens/Settings.tsx:718
|
||||
#: src/view/screens/Settings.tsx:751
|
||||
msgid "Build version {0} {1}"
|
||||
msgstr "ビルドバージョン {0} {1}"
|
||||
|
||||
@@ -345,9 +346,8 @@ msgstr "カメラ"
|
||||
msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must be at least 4 characters long, but no more than 32 characters long."
|
||||
msgstr "文字、数字、スペース、ハイフン、およびアンダースコアのみが使用可能です。長さは4文字以上32文字以下である必要があります。"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:289
|
||||
#: src/view/com/composer/Composer.tsx:292
|
||||
#: src/view/com/modals/AltImage.tsx:128
|
||||
#: src/view/com/composer/Composer.tsx:294
|
||||
#: src/view/com/composer/Composer.tsx:297
|
||||
#: src/view/com/modals/ChangeEmail.tsx:218
|
||||
#: src/view/com/modals/ChangeEmail.tsx:220
|
||||
#: src/view/com/modals/Confirm.tsx:88
|
||||
@@ -371,8 +371,8 @@ msgid "Cancel account deletion"
|
||||
msgstr "アカウントの削除をキャンセル"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:123
|
||||
msgid "Cancel add image alt text"
|
||||
msgstr "画像のALTテキストの追加をキャンセル"
|
||||
#~ msgid "Cancel add image alt text"
|
||||
#~ msgstr "画像のALTテキストの追加をキャンセル"
|
||||
|
||||
#: src/view/com/modals/ChangeHandle.tsx:149
|
||||
msgid "Cancel change handle"
|
||||
@@ -403,8 +403,8 @@ msgstr "Waitlistの登録をキャンセル"
|
||||
msgid "Change"
|
||||
msgstr "変更"
|
||||
|
||||
#: src/view/screens/Settings.tsx:601
|
||||
#: src/view/screens/Settings.tsx:610
|
||||
#: src/view/screens/Settings.tsx:634
|
||||
#: src/view/screens/Settings.tsx:643
|
||||
msgid "Change handle"
|
||||
msgstr "ハンドルを変更"
|
||||
|
||||
@@ -434,7 +434,7 @@ msgstr "入力したメールアドレスの受信トレイを確認して、以
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:72
|
||||
msgid "Choose \"Everybody\" or \"Nobody\""
|
||||
msgstr ""
|
||||
msgstr "「全員」と「返信不可」のどちらかを選択"
|
||||
|
||||
#: src/view/com/modals/ServerInput.tsx:38
|
||||
msgid "Choose Service"
|
||||
@@ -448,19 +448,19 @@ msgstr "カスタムフィードを使用してあなたの体験を強化する
|
||||
msgid "Choose your password"
|
||||
msgstr "パスワードを選択"
|
||||
|
||||
#: src/view/screens/Settings.tsx:694
|
||||
#: src/view/screens/Settings.tsx:727
|
||||
msgid "Clear all legacy storage data"
|
||||
msgstr "レガシーストレージデータをすべてクリア"
|
||||
|
||||
#: src/view/screens/Settings.tsx:696
|
||||
#: src/view/screens/Settings.tsx:729
|
||||
msgid "Clear all legacy storage data (restart after this)"
|
||||
msgstr "すべてのレガシーストレージデータをクリア(この後再起動します)"
|
||||
|
||||
#: src/view/screens/Settings.tsx:706
|
||||
#: src/view/screens/Settings.tsx:739
|
||||
msgid "Clear all storage data"
|
||||
msgstr "すべてのストレージデータをクリア"
|
||||
|
||||
#: src/view/screens/Settings.tsx:708
|
||||
#: src/view/screens/Settings.tsx:741
|
||||
msgid "Clear all storage data (restart after this)"
|
||||
msgstr "すべてのストレージデータをクリア(この後再起動します)"
|
||||
|
||||
@@ -501,8 +501,8 @@ msgstr "返信を作成"
|
||||
#: src/view/com/modals/Confirm.tsx:75
|
||||
#: src/view/com/modals/SelfLabel.tsx:154
|
||||
#: src/view/com/modals/VerifyEmail.tsx:225
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:299
|
||||
#: src/view/screens/PreferencesThreads.tsx:153
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:305
|
||||
#: src/view/screens/PreferencesThreads.tsx:159
|
||||
msgid "Confirm"
|
||||
msgstr "確認"
|
||||
|
||||
@@ -526,7 +526,7 @@ msgid "Confirmation code"
|
||||
msgstr "確認コード"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:269
|
||||
#: src/view/com/auth/login/LoginForm.tsx:273
|
||||
msgid "Connecting..."
|
||||
msgstr "接続中..."
|
||||
|
||||
@@ -616,11 +616,15 @@ msgstr "作成済み {0}"
|
||||
msgid "Custom domain"
|
||||
msgstr "カスタムドメイン"
|
||||
|
||||
#: src/view/screens/Settings.tsx:615
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:55
|
||||
msgid "Customize media from external sites."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/Settings.tsx:648
|
||||
msgid "Danger Zone"
|
||||
msgstr "危険地帯"
|
||||
|
||||
#: src/view/screens/Settings.tsx:622
|
||||
#: src/view/screens/Settings.tsx:655
|
||||
msgid "Delete account"
|
||||
msgstr "アカウントを削除"
|
||||
|
||||
@@ -642,7 +646,7 @@ msgstr "リストを削除"
|
||||
msgid "Delete my account"
|
||||
msgstr "マイアカウントを削除"
|
||||
|
||||
#: src/view/screens/Settings.tsx:632
|
||||
#: src/view/screens/Settings.tsx:665
|
||||
msgid "Delete my account…"
|
||||
msgstr "マイアカウントを削除…"
|
||||
|
||||
@@ -669,19 +673,19 @@ msgstr "説明"
|
||||
msgid "Dev Server"
|
||||
msgstr "開発者サーバー"
|
||||
|
||||
#: src/view/screens/Settings.tsx:637
|
||||
#: src/view/screens/Settings.tsx:670
|
||||
msgid "Developer Tools"
|
||||
msgstr "開発者ツール"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:210
|
||||
#: src/view/com/composer/Composer.tsx:211
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:143
|
||||
#: src/view/com/composer/Composer.tsx:144
|
||||
msgid "Discard"
|
||||
msgstr "破棄"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:137
|
||||
#: src/view/com/composer/Composer.tsx:138
|
||||
msgid "Discard draft"
|
||||
msgstr "下書きを破棄"
|
||||
|
||||
@@ -706,6 +710,7 @@ msgid "Domain verified!"
|
||||
msgstr "ドメインを確認しました!"
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFollows.tsx:86
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:88
|
||||
#: src/view/com/modals/ContentFilteringSettings.tsx:96
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:152
|
||||
@@ -715,8 +720,8 @@ msgstr "ドメインを確認しました!"
|
||||
#: src/view/com/modals/Threadgate.tsx:129
|
||||
#: src/view/com/modals/Threadgate.tsx:132
|
||||
#: src/view/com/modals/UserAddRemoveLists.tsx:79
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:302
|
||||
#: src/view/screens/PreferencesThreads.tsx:156
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:308
|
||||
#: src/view/screens/PreferencesThreads.tsx:162
|
||||
msgid "Done"
|
||||
msgstr "完了"
|
||||
|
||||
@@ -777,7 +782,15 @@ msgstr "メールアドレスを更新"
|
||||
msgid "Email:"
|
||||
msgstr "メールアドレス:"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:138
|
||||
#: src/view/com/modals/EmbedConsent.tsx:113
|
||||
msgid "Enable {0} only"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:97
|
||||
msgid "Enable External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:144
|
||||
msgid "Enable this setting to only see replies between people you follow."
|
||||
msgstr "この設定を有効にすると、自分がフォローしているユーザーからの返信だけが表示されます。"
|
||||
|
||||
@@ -821,6 +834,20 @@ msgstr "全員"
|
||||
msgid "Expand alt text"
|
||||
msgstr "ALTテキストを展開"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:64
|
||||
msgid "External Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:75
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:66
|
||||
msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesExternalEmbeds.tsx:52
|
||||
#: src/view/screens/Settings.tsx:595
|
||||
msgid "External Media Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:109
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:141
|
||||
msgid "Failed to load recommended feeds"
|
||||
@@ -868,7 +895,7 @@ msgstr "右側の検索ツールでユーザーを検索"
|
||||
msgid "Finding similar accounts..."
|
||||
msgstr "似ているアカウントを検索中..."
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:102
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:108
|
||||
msgid "Fine-tune the content you see on your home screen."
|
||||
msgstr "ホーム画面に表示されるコンテンツを微調整します。"
|
||||
|
||||
@@ -888,7 +915,7 @@ msgstr "何人かのユーザーをフォローして開始します。興味を
|
||||
msgid "Followed users"
|
||||
msgstr "自分がフォローしているユーザー"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:145
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:151
|
||||
msgid "Followed users only"
|
||||
msgstr "自分がフォローしているユーザーのみ"
|
||||
|
||||
@@ -917,11 +944,11 @@ msgstr "セキュリティ上の理由から、メールアドレスに確認コ
|
||||
msgid "For security reasons, you won't be able to view this again. If you lose this password, you'll need to generate a new one."
|
||||
msgstr "セキュリティ上の理由から、これを再度表示することはできません。このパスワードを紛失した場合は、新しいパスワードを生成する必要があります。"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:232
|
||||
#: src/view/com/auth/login/LoginForm.tsx:236
|
||||
msgid "Forgot"
|
||||
msgstr "忘れた"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:229
|
||||
#: src/view/com/auth/login/LoginForm.tsx:233
|
||||
msgid "Forgot password"
|
||||
msgstr "パスワードを忘れた"
|
||||
|
||||
@@ -953,7 +980,7 @@ msgid "Go Back"
|
||||
msgstr "戻る"
|
||||
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:181
|
||||
#: src/view/com/auth/login/LoginForm.tsx:279
|
||||
#: src/view/com/auth/login/LoginForm.tsx:283
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:163
|
||||
msgid "Go to next"
|
||||
msgstr "次へ"
|
||||
@@ -978,11 +1005,11 @@ msgstr "非表示"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:173
|
||||
msgid "Hide post"
|
||||
msgstr ""
|
||||
msgstr "投稿を非表示にする"
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:177
|
||||
msgid "Hide this post?"
|
||||
msgstr ""
|
||||
msgstr "この投稿を非表示にしますか?"
|
||||
|
||||
#: src/view/com/notifications/FeedItem.tsx:316
|
||||
msgid "Hide user list"
|
||||
@@ -1016,7 +1043,7 @@ msgid "Home"
|
||||
msgstr "ホーム"
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:96
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:95
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:101
|
||||
#: src/view/screens/Settings.tsx:481
|
||||
msgid "Home Feed Preferences"
|
||||
msgstr "ホームフィードの設定"
|
||||
@@ -1051,7 +1078,7 @@ msgstr "画像のALTテキスト"
|
||||
msgid "Image options"
|
||||
msgstr "画像のオプション"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:113
|
||||
#: src/view/com/auth/login/LoginForm.tsx:115
|
||||
msgid "Invalid username or password"
|
||||
msgstr "無効なユーザー名またはパスワード"
|
||||
|
||||
@@ -1204,7 +1231,7 @@ msgstr "ローカル開発者サーバー"
|
||||
|
||||
#: src/view/screens/Moderation.tsx:136
|
||||
msgid "Logged-out visibility"
|
||||
msgstr "ログアウトした状態の可視性"
|
||||
msgstr "ログアウトしたユーザーからの可視性"
|
||||
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:133
|
||||
msgid "Login to account that is not listed"
|
||||
@@ -1264,6 +1291,10 @@ msgstr "その他のフィード"
|
||||
msgid "More options"
|
||||
msgstr "その他のオプション"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:82
|
||||
msgid "Most-liked replies first"
|
||||
msgstr "いいねの数が多い順に返信を表示"
|
||||
|
||||
#: src/view/com/profile/ProfileHeader.tsx:370
|
||||
msgid "Mute Account"
|
||||
msgstr "アカウントをミュート"
|
||||
@@ -1321,6 +1352,11 @@ msgstr "保存されたフィード"
|
||||
msgid "Name"
|
||||
msgstr "名前"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:107
|
||||
#: src/view/com/modals/EmbedConsent.tsx:123
|
||||
msgid "Never load embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/onboarding/WelcomeMobile.tsx:72
|
||||
msgid "Never lose access to your followers and data."
|
||||
msgstr "フォロワーやデータへのアクセスを失うことはありません。"
|
||||
@@ -1344,10 +1380,14 @@ msgstr "新しい投稿"
|
||||
msgid "New Post"
|
||||
msgstr "新しい投稿"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:79
|
||||
msgid "Newest replies first"
|
||||
msgstr "新しい順に返信を表示"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:154
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:174
|
||||
#: src/view/com/auth/login/ForgotPasswordForm.tsx:184
|
||||
#: src/view/com/auth/login/LoginForm.tsx:282
|
||||
#: src/view/com/auth/login/LoginForm.tsx:286
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:156
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:166
|
||||
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:79
|
||||
@@ -1358,10 +1398,12 @@ msgstr "次へ"
|
||||
msgid "Next image"
|
||||
msgstr "次の画像"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:191
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:226
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:263
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:197
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:232
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:269
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "No"
|
||||
msgstr "いいえ"
|
||||
|
||||
@@ -1386,6 +1428,10 @@ msgstr "「{query}」の検索結果はありません"
|
||||
msgid "No results found for {query}"
|
||||
msgstr "「{query}」の検索結果はありません"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:129
|
||||
msgid "No thanks"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:82
|
||||
msgid "Nobody"
|
||||
msgstr "返信不可"
|
||||
@@ -1419,7 +1465,11 @@ msgstr "ちょっと!"
|
||||
msgid "Okay"
|
||||
msgstr "OK"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:358
|
||||
#: src/view/screens/PreferencesThreads.tsx:78
|
||||
msgid "Oldest replies first"
|
||||
msgstr "古い順に返信を表示"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:363
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr "1つもしくは複数の画像にALTテキストがありません。"
|
||||
|
||||
@@ -1427,6 +1477,11 @@ msgstr "1つもしくは複数の画像にALTテキストがありません。"
|
||||
msgid "Only {0} can reply."
|
||||
msgstr "{0}のみ返信可能"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
#: src/view/com/composer/Composer.tsx:469
|
||||
msgid "Open emoji picker"
|
||||
msgstr "絵文字を入力"
|
||||
|
||||
#: src/view/com/pager/FeedsTabBarMobile.tsx:76
|
||||
msgid "Open navigation"
|
||||
msgstr "ナビゲーションを開く"
|
||||
@@ -1435,6 +1490,10 @@ msgstr "ナビゲーションを開く"
|
||||
msgid "Opens configurable language settings"
|
||||
msgstr "構成可能な言語設定を開く"
|
||||
|
||||
#: src/view/screens/Settings.tsx:587
|
||||
msgid "Opens external embeds settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/shell/desktop/RightNav.tsx:156
|
||||
#: src/view/shell/Drawer.tsx:641
|
||||
msgid "Opens list of invite codes"
|
||||
@@ -1452,7 +1511,7 @@ msgstr "モデレーションの設定を開く"
|
||||
msgid "Opens screen with all saved feeds"
|
||||
msgstr "保存されたすべてのフィードで画面を開く"
|
||||
|
||||
#: src/view/screens/Settings.tsx:581
|
||||
#: src/view/screens/Settings.tsx:614
|
||||
msgid "Opens the app password settings page"
|
||||
msgstr "アプリパスワード設定ページを開く"
|
||||
|
||||
@@ -1460,11 +1519,11 @@ msgstr "アプリパスワード設定ページを開く"
|
||||
msgid "Opens the home feed preferences"
|
||||
msgstr "ホームフィードの設定を開く"
|
||||
|
||||
#: src/view/screens/Settings.tsx:664
|
||||
#: src/view/screens/Settings.tsx:697
|
||||
msgid "Opens the storybook page"
|
||||
msgstr "ストーリーブックのページを開く"
|
||||
|
||||
#: src/view/screens/Settings.tsx:644
|
||||
#: src/view/screens/Settings.tsx:677
|
||||
msgid "Opens the system log page"
|
||||
msgstr "システムログのページを開く"
|
||||
|
||||
@@ -1474,7 +1533,7 @@ msgstr "スレッドの設定を開く"
|
||||
|
||||
#: src/view/com/modals/Threadgate.tsx:89
|
||||
msgid "Or combine these options:"
|
||||
msgstr ""
|
||||
msgstr "または以下のオプションを組み合わせてください:"
|
||||
|
||||
#: src/view/com/auth/login/ChooseAccountForm.tsx:138
|
||||
msgid "Other account"
|
||||
@@ -1495,7 +1554,7 @@ msgstr "ページが見つかりません"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:122
|
||||
#: src/view/com/auth/create/Step2.tsx:132
|
||||
#: src/view/com/auth/login/LoginForm.tsx:217
|
||||
#: src/view/com/auth/login/LoginForm.tsx:221
|
||||
#: src/view/com/auth/login/SetNewPasswordForm.tsx:130
|
||||
#: src/view/com/modals/DeleteAccount.tsx:191
|
||||
msgid "Password"
|
||||
@@ -1517,6 +1576,19 @@ msgstr "成人向けの写真です。"
|
||||
msgid "Pinned Feeds"
|
||||
msgstr "ピン留めされたフィード"
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:111
|
||||
msgid "Play {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:54
|
||||
#: src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx:55
|
||||
msgid "Play Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/ExternalGifEmbed.tsx:110
|
||||
msgid "Plays the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/auth/create/state.ts:116
|
||||
msgid "Please choose your handle."
|
||||
msgstr "ハンドルをお選びください。"
|
||||
@@ -1551,11 +1623,11 @@ msgstr ""
|
||||
#~ msgid "Please tell us why you think this decision was incorrect."
|
||||
#~ msgstr "この判断が誤っていると考える理由を教えてください。"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:214
|
||||
#: src/view/com/composer/Composer.tsx:215
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
msgstr "リンクカードがロードされるまでお待ちください"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:341
|
||||
#: src/view/com/composer/Composer.tsx:346
|
||||
#: src/view/com/post-thread/PostThread.tsx:225
|
||||
#: src/view/screens/PostThread.tsx:80
|
||||
msgid "Post"
|
||||
@@ -1593,16 +1665,17 @@ msgstr "前の画像"
|
||||
msgid "Primary Language"
|
||||
msgstr "第一言語"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:91
|
||||
#: src/view/screens/PreferencesThreads.tsx:97
|
||||
msgid "Prioritize Your Follows"
|
||||
msgstr "あなたのフォローを優先"
|
||||
|
||||
#: src/view/screens/Settings.tsx:570
|
||||
#: src/view/shell/desktop/RightNav.tsx:84
|
||||
msgid "Privacy"
|
||||
msgstr "プライバシー"
|
||||
|
||||
#: src/view/screens/PrivacyPolicy.tsx:29
|
||||
#: src/view/screens/Settings.tsx:750
|
||||
#: src/view/screens/Settings.tsx:783
|
||||
#: src/view/shell/Drawer.tsx:262
|
||||
msgid "Privacy Policy"
|
||||
msgstr "プライバシーポリシー"
|
||||
@@ -1619,7 +1692,7 @@ msgstr "処理中..."
|
||||
msgid "Profile"
|
||||
msgstr "プロフィール"
|
||||
|
||||
#: src/view/screens/Settings.tsx:808
|
||||
#: src/view/screens/Settings.tsx:841
|
||||
msgid "Protect your account by verifying your email."
|
||||
msgstr "メールアドレスを確認してアカウントを保護します。"
|
||||
|
||||
@@ -1640,6 +1713,10 @@ msgstr "引用"
|
||||
msgid "Quote Post"
|
||||
msgstr "引用"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:86
|
||||
msgid "Random (aka \"Poster's Roulette\")"
|
||||
msgstr "ランダムな順番で表示(別名「投稿者のルーレット」)"
|
||||
|
||||
#: src/view/com/modals/EditImage.tsx:236
|
||||
msgid "Ratios"
|
||||
msgstr "比率"
|
||||
@@ -1707,7 +1784,7 @@ msgstr "返信"
|
||||
msgid "Replies to this thread are disabled"
|
||||
msgstr "このスレッドへの返信はできません"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:135
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:141
|
||||
msgid "Reply Filters"
|
||||
msgstr "返信のフィルター"
|
||||
|
||||
@@ -1750,6 +1827,10 @@ msgstr "リポストしたユーザー"
|
||||
msgid "Request Change"
|
||||
msgstr "変更を要求"
|
||||
|
||||
#: src/view/screens/Settings.tsx:422
|
||||
msgid "Require alt text before posting"
|
||||
msgstr "画像投稿時にALTテキストを必須とする"
|
||||
|
||||
#: src/view/com/auth/create/Step2.tsx:68
|
||||
msgid "Required for this provider"
|
||||
msgstr "このプロバイダーに必要"
|
||||
@@ -1758,7 +1839,7 @@ msgstr "このプロバイダーに必要"
|
||||
msgid "Reset code"
|
||||
msgstr "コードをリセット"
|
||||
|
||||
#: src/view/screens/Settings.tsx:686
|
||||
#: src/view/screens/Settings.tsx:719
|
||||
msgid "Reset onboarding state"
|
||||
msgstr "オンボーディングの状態をリセット"
|
||||
|
||||
@@ -1766,28 +1847,27 @@ msgstr "オンボーディングの状態をリセット"
|
||||
msgid "Reset password"
|
||||
msgstr "パスワードをリセット"
|
||||
|
||||
#: src/view/screens/Settings.tsx:676
|
||||
#: src/view/screens/Settings.tsx:709
|
||||
msgid "Reset preferences state"
|
||||
msgstr "設定をリセット"
|
||||
|
||||
#: src/view/screens/Settings.tsx:684
|
||||
#: src/view/screens/Settings.tsx:717
|
||||
msgid "Resets the onboarding state"
|
||||
msgstr "オンボーディングの状態をリセット"
|
||||
|
||||
#: src/view/screens/Settings.tsx:674
|
||||
#: src/view/screens/Settings.tsx:707
|
||||
msgid "Resets the preferences state"
|
||||
msgstr "設定の状態をリセット"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:163
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:167
|
||||
#: src/view/com/auth/login/LoginForm.tsx:259
|
||||
#: src/view/com/auth/login/LoginForm.tsx:262
|
||||
#: src/view/com/auth/login/LoginForm.tsx:263
|
||||
#: src/view/com/auth/login/LoginForm.tsx:266
|
||||
#: src/view/com/util/error/ErrorMessage.tsx:55
|
||||
#: src/view/com/util/error/ErrorScreen.tsx:65
|
||||
msgid "Retry"
|
||||
msgstr "再試行"
|
||||
|
||||
#: src/view/com/modals/AltImage.tsx:115
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:94
|
||||
#: src/view/com/modals/BirthDateSettings.tsx:97
|
||||
#: src/view/com/modals/ChangeHandle.tsx:173
|
||||
@@ -1837,7 +1917,7 @@ msgstr "検索"
|
||||
#: src/view/com/auth/LoggedOut.tsx:104
|
||||
#: src/view/com/auth/LoggedOut.tsx:105
|
||||
msgid "Search for users"
|
||||
msgstr ""
|
||||
msgstr "ユーザーを検索"
|
||||
|
||||
#: src/view/com/modals/ChangeEmail.tsx:110
|
||||
msgid "Security Step Required"
|
||||
@@ -1855,7 +1935,7 @@ msgstr "Bluesky Socialを選択"
|
||||
msgid "Select from an existing account"
|
||||
msgstr "既存のアカウントから選択"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:143
|
||||
#: src/view/com/auth/login/LoginForm.tsx:147
|
||||
msgid "Select service"
|
||||
msgstr "サービスを選択"
|
||||
|
||||
@@ -1896,25 +1976,25 @@ msgstr "報告を送信"
|
||||
msgid "Set new password"
|
||||
msgstr "新しいパスワードを設定"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:216
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:222
|
||||
msgid "Set this setting to \"No\" to hide all quote posts from your feed. Reposts will still be visible."
|
||||
msgstr "フィード内の引用をすべて非表示にするには、この設定を「いいえ」にします。リポストは引き続き表示されます。"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:113
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:119
|
||||
msgid "Set this setting to \"No\" to hide all replies from your feed."
|
||||
msgstr "フィード内の返信をすべて非表示にするには、この設定を「いいえ」にします。"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:182
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:188
|
||||
msgid "Set this setting to \"No\" to hide all reposts from your feed."
|
||||
msgstr "フィード内のリポストをすべて非表示にするには、この設定を「いいえ」にします。"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:116
|
||||
#: src/view/screens/PreferencesThreads.tsx:122
|
||||
msgid "Set this setting to \"Yes\" to show replies in a threaded view. This is an experimental feature."
|
||||
msgstr "スレッド表示で返信を表示するには、この設定を「はい」にします。これは実験的な機能です。"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:252
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:258
|
||||
msgid "Set this setting to \"Yes\" to show samples of your saved feeds in your following feed. This is an experimental feature."
|
||||
msgstr "保存されたフィードのサンプルを次のフィードに表示するには、この設定を「はい」にします。これは実験的な機能です。"
|
||||
msgstr "保存されたフィードから投稿を抽出して「Following」フィードに表示するには、この設定を「はい」にします。これは実験的な機能です。"
|
||||
|
||||
#: src/view/screens/Settings.tsx:277
|
||||
#: src/view/shell/desktop/LeftNav.tsx:433
|
||||
@@ -1946,23 +2026,27 @@ msgstr "表示"
|
||||
msgid "Show anyway"
|
||||
msgstr "とにかく表示"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:249
|
||||
#: src/view/com/modals/EmbedConsent.tsx:87
|
||||
msgid "Show embeds from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:255
|
||||
msgid "Show Posts from My Feeds"
|
||||
msgstr "マイフィードからの投稿を表示"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:213
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:219
|
||||
msgid "Show Quote Posts"
|
||||
msgstr "引用を表示"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:110
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:116
|
||||
msgid "Show Replies"
|
||||
msgstr "返信を表示"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:94
|
||||
#: src/view/screens/PreferencesThreads.tsx:100
|
||||
msgid "Show replies by people you follow before all other replies."
|
||||
msgstr "自分がフォローしているユーザーからの返信を、他のすべての返信の前に表示します。"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:179
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:185
|
||||
msgid "Show Reposts"
|
||||
msgstr "リポストを表示"
|
||||
|
||||
@@ -1999,7 +2083,7 @@ msgstr "{0}としてサインイン"
|
||||
msgid "Sign in as..."
|
||||
msgstr "アカウントの選択"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:130
|
||||
#: src/view/com/auth/login/LoginForm.tsx:134
|
||||
msgid "Sign into"
|
||||
msgstr "サインイン"
|
||||
|
||||
@@ -2053,11 +2137,11 @@ msgstr "正方形"
|
||||
msgid "Staging"
|
||||
msgstr "ステージング"
|
||||
|
||||
#: src/view/screens/Settings.tsx:730
|
||||
#: src/view/screens/Settings.tsx:763
|
||||
msgid "Status page"
|
||||
msgstr "ステータスページ"
|
||||
|
||||
#: src/view/screens/Settings.tsx:666
|
||||
#: src/view/screens/Settings.tsx:699
|
||||
msgid "Storybook"
|
||||
msgstr "ストーリーブック"
|
||||
|
||||
@@ -2086,7 +2170,7 @@ msgstr "サポート"
|
||||
msgid "Switch Account"
|
||||
msgstr "アカウントを切り替える"
|
||||
|
||||
#: src/view/screens/Settings.tsx:646
|
||||
#: src/view/screens/Settings.tsx:679
|
||||
msgid "System log"
|
||||
msgstr "システムログ"
|
||||
|
||||
@@ -2098,7 +2182,7 @@ msgstr "トール"
|
||||
msgid "Terms"
|
||||
msgstr "条件"
|
||||
|
||||
#: src/view/screens/Settings.tsx:744
|
||||
#: src/view/screens/Settings.tsx:777
|
||||
#: src/view/screens/TermsOfService.tsx:29
|
||||
#: src/view/shell/Drawer.tsx:256
|
||||
msgid "Terms of Service"
|
||||
@@ -2153,6 +2237,10 @@ msgstr "この{screenDescription}にはフラグが設定されています:"
|
||||
msgid "This account has requested that users sign in to view their profile."
|
||||
msgstr "このアカウントを閲覧するためにはサインインが必要です。"
|
||||
|
||||
#: src/view/com/modals/EmbedConsent.tsx:68
|
||||
msgid "This content is hosted by {0}. Do you want to enable external media?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/posts/FeedErrorMessage.tsx:107
|
||||
msgid "This content is not viewable without a Bluesky account."
|
||||
msgstr "このコンテンツはBlueskyのアカウントがないと閲覧できません。"
|
||||
@@ -2187,14 +2275,14 @@ msgstr "この警告は、メディアが接続されている投稿にのみ使
|
||||
|
||||
#: src/view/com/util/forms/PostDropdownBtn.tsx:178
|
||||
msgid "This will hide this post from your feeds."
|
||||
msgstr ""
|
||||
msgstr "この投稿をあなたのフィードにおいて非表示にします。"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:53
|
||||
#: src/view/screens/Settings.tsx:503
|
||||
msgid "Thread Preferences"
|
||||
msgstr "スレッドの設定"
|
||||
|
||||
#: src/view/screens/PreferencesThreads.tsx:113
|
||||
#: src/view/screens/PreferencesThreads.tsx:119
|
||||
msgid "Threaded Mode"
|
||||
msgstr "スレッドモード"
|
||||
|
||||
@@ -2226,7 +2314,7 @@ msgstr "リストでのミュートを解除"
|
||||
|
||||
#: src/view/com/auth/create/CreateAccount.tsx:65
|
||||
#: src/view/com/auth/login/Login.tsx:76
|
||||
#: src/view/com/auth/login/LoginForm.tsx:117
|
||||
#: src/view/com/auth/login/LoginForm.tsx:120
|
||||
msgid "Unable to contact your service. Please check your Internet connection."
|
||||
msgstr "あなたのサービスに接続できません。インターネットの接続を確認してください。"
|
||||
|
||||
@@ -2244,7 +2332,7 @@ msgstr "アカウントのブロックを解除"
|
||||
msgid "Undo repost"
|
||||
msgstr "リポストを元に戻す"
|
||||
|
||||
#: src/view/com/auth/create/state.ts:210
|
||||
#: src/view/com/auth/create/state.ts:216
|
||||
msgid "Unfortunately, you do not meet the requirements to create an account."
|
||||
msgstr "残念ながら、アカウントを作成するための要件を満たしていません。"
|
||||
|
||||
@@ -2300,8 +2388,8 @@ msgstr "ユーザーハンドル"
|
||||
msgid "User Lists"
|
||||
msgstr "ユーザーリスト"
|
||||
|
||||
#: src/view/com/auth/login/LoginForm.tsx:170
|
||||
#: src/view/com/auth/login/LoginForm.tsx:188
|
||||
#: src/view/com/auth/login/LoginForm.tsx:174
|
||||
#: src/view/com/auth/login/LoginForm.tsx:192
|
||||
msgid "Username or email address"
|
||||
msgstr "ユーザー名またはメールアドレス"
|
||||
|
||||
@@ -2317,15 +2405,15 @@ msgstr "<0/>にフォローされているユーザー"
|
||||
msgid "Users in \"{0}\""
|
||||
msgstr "{0}のユーザー"
|
||||
|
||||
#: src/view/screens/Settings.tsx:769
|
||||
#: src/view/screens/Settings.tsx:802
|
||||
msgid "Verify email"
|
||||
msgstr "メールアドレスを確認"
|
||||
|
||||
#: src/view/screens/Settings.tsx:794
|
||||
#: src/view/screens/Settings.tsx:827
|
||||
msgid "Verify my email"
|
||||
msgstr "メールアドレスを確認"
|
||||
|
||||
#: src/view/screens/Settings.tsx:803
|
||||
#: src/view/screens/Settings.tsx:836
|
||||
msgid "Verify My Email"
|
||||
msgstr "メールアドレスを確認"
|
||||
|
||||
@@ -2387,7 +2475,7 @@ msgstr "返信できるユーザー"
|
||||
msgid "Wide"
|
||||
msgstr "ワイド"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:413
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
msgid "Write post"
|
||||
msgstr "投稿を書く"
|
||||
|
||||
@@ -2395,10 +2483,12 @@ msgstr "投稿を書く"
|
||||
msgid "Write your reply"
|
||||
msgstr "返信を書く"
|
||||
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:120
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:192
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:227
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:262
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:126
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:198
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:233
|
||||
#: src/view/screens/PreferencesHomeFeed.tsx:268
|
||||
#: src/view/screens/PreferencesThreads.tsx:106
|
||||
#: src/view/screens/PreferencesThreads.tsx:129
|
||||
msgid "Yes"
|
||||
msgstr "はい"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@ export const router = new Router({
|
||||
AppPasswords: '/settings/app-passwords',
|
||||
PreferencesHomeFeed: '/settings/home-feed',
|
||||
PreferencesThreads: '/settings/threads',
|
||||
PreferencesExternalEmbeds: '/settings/external-embeds',
|
||||
SavedFeeds: '/settings/saved-feeds',
|
||||
Support: '/support',
|
||||
PrivacyPolicy: '/support/privacy',
|
||||
|
||||
@@ -6,6 +6,7 @@ import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||
import {ImageModel} from '#/state/models/media/image'
|
||||
import {GalleryModel} from '#/state/models/media/gallery'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {EmbedPlayerSource} from '#/lib/strings/embed-player.ts'
|
||||
import {ThreadgateSetting} from '../queries/threadgate'
|
||||
|
||||
export interface ConfirmModal {
|
||||
@@ -180,6 +181,12 @@ export interface LinkWarningModal {
|
||||
href: string
|
||||
}
|
||||
|
||||
export interface EmbedConsentModal {
|
||||
name: 'embed-consent'
|
||||
source: EmbedPlayerSource
|
||||
onAccept: () => void
|
||||
}
|
||||
|
||||
export type Modal =
|
||||
// Account
|
||||
| AddAppPasswordModal
|
||||
@@ -223,6 +230,7 @@ export type Modal =
|
||||
// Generic
|
||||
| ConfirmModal
|
||||
| LinkWarningModal
|
||||
| EmbedConsentModal
|
||||
|
||||
const ModalContext = React.createContext<{
|
||||
isModalActive: boolean
|
||||
|
||||
@@ -109,6 +109,7 @@ export function transform(legacy: Partial<LegacySchema>): Schema {
|
||||
step: legacy.onboarding?.step || defaults.onboarding.step,
|
||||
},
|
||||
hiddenPosts: defaults.hiddenPosts,
|
||||
externalEmbeds: defaults.externalEmbeds,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {z} from 'zod'
|
||||
import {deviceLocales} from '#/platform/detection'
|
||||
|
||||
const externalEmbedOptions = ['show', 'hide'] as const
|
||||
|
||||
// only data needed for rendering account page
|
||||
const accountSchema = z.object({
|
||||
service: z.string(),
|
||||
@@ -30,6 +32,19 @@ export const schema = z.object({
|
||||
appLanguage: z.string(),
|
||||
}),
|
||||
requireAltTextEnabled: z.boolean(), // should move to server
|
||||
externalEmbeds: z
|
||||
.object({
|
||||
giphy: z.enum(externalEmbedOptions).optional(),
|
||||
tenor: z.enum(externalEmbedOptions).optional(),
|
||||
youtube: z.enum(externalEmbedOptions).optional(),
|
||||
youtubeShorts: z.enum(externalEmbedOptions).optional(),
|
||||
twitch: z.enum(externalEmbedOptions).optional(),
|
||||
vimeo: z.enum(externalEmbedOptions).optional(),
|
||||
spotify: z.enum(externalEmbedOptions).optional(),
|
||||
appleMusic: z.enum(externalEmbedOptions).optional(),
|
||||
soundcloud: z.enum(externalEmbedOptions).optional(),
|
||||
})
|
||||
.optional(),
|
||||
mutedThreads: z.array(z.string()), // should move to server
|
||||
invites: z.object({
|
||||
copiedInvites: z.array(z.string()),
|
||||
@@ -60,6 +75,7 @@ export const defaults: Schema = {
|
||||
appLanguage: deviceLocales[0] || 'en',
|
||||
},
|
||||
requireAltTextEnabled: false,
|
||||
externalEmbeds: {},
|
||||
mutedThreads: [],
|
||||
invites: {
|
||||
copiedInvites: [],
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from 'react'
|
||||
import * as persisted from '#/state/persisted'
|
||||
import {EmbedPlayerSource} from 'lib/strings/embed-player'
|
||||
|
||||
type StateContext = persisted.Schema['externalEmbeds']
|
||||
type SetContext = (source: EmbedPlayerSource, value: 'show' | 'hide') => void
|
||||
|
||||
const stateContext = React.createContext<StateContext>(
|
||||
persisted.defaults.externalEmbeds,
|
||||
)
|
||||
const setContext = React.createContext<SetContext>({} as SetContext)
|
||||
|
||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
const [state, setState] = React.useState(persisted.get('externalEmbeds'))
|
||||
|
||||
const setStateWrapped = React.useCallback(
|
||||
(source: EmbedPlayerSource, value: 'show' | 'hide') => {
|
||||
setState(prev => {
|
||||
persisted.write('externalEmbeds', {
|
||||
...prev,
|
||||
[source]: value,
|
||||
})
|
||||
|
||||
return {
|
||||
...prev,
|
||||
[source]: value,
|
||||
}
|
||||
})
|
||||
},
|
||||
[setState],
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
return persisted.onUpdate(() => {
|
||||
setState(persisted.get('externalEmbeds'))
|
||||
})
|
||||
}, [setStateWrapped])
|
||||
|
||||
return (
|
||||
<stateContext.Provider value={state}>
|
||||
<setContext.Provider value={setStateWrapped}>
|
||||
{children}
|
||||
</setContext.Provider>
|
||||
</stateContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useExternalEmbedsPrefs() {
|
||||
return React.useContext(stateContext)
|
||||
}
|
||||
|
||||
export function useSetExternalEmbedPref() {
|
||||
return React.useContext(setContext)
|
||||
}
|
||||
@@ -2,19 +2,26 @@ import React from 'react'
|
||||
import {Provider as LanguagesProvider} from './languages'
|
||||
import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-required'
|
||||
import {Provider as HiddenPostsProvider} from '../preferences/hidden-posts'
|
||||
import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs'
|
||||
|
||||
export {useLanguagePrefs, useLanguagePrefsApi} from './languages'
|
||||
export {
|
||||
useRequireAltTextEnabled,
|
||||
useSetRequireAltTextEnabled,
|
||||
} from './alt-text-required'
|
||||
export {
|
||||
useExternalEmbedsPrefs,
|
||||
useSetExternalEmbedPref,
|
||||
} from './external-embeds-prefs'
|
||||
export * from './hidden-posts'
|
||||
|
||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
return (
|
||||
<LanguagesProvider>
|
||||
<AltTextRequiredProvider>
|
||||
<HiddenPostsProvider>{children}</HiddenPostsProvider>
|
||||
<ExternalEmbedsProvider>
|
||||
<HiddenPostsProvider>{children}</HiddenPostsProvider>
|
||||
</ExternalEmbedsProvider>
|
||||
</AltTextRequiredProvider>
|
||||
</LanguagesProvider>
|
||||
)
|
||||
|
||||
@@ -24,6 +24,8 @@ export function useActorAutocompleteQuery(prefix: string) {
|
||||
const {data: follows, isFetching} = useMyFollowsQuery()
|
||||
const moderationOpts = useModerationOpts()
|
||||
|
||||
prefix = prefix.toLowerCase()
|
||||
|
||||
return useQuery<AppBskyActorDefs.ProfileViewBasic[]>({
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(prefix || ''),
|
||||
|
||||
@@ -9,7 +9,6 @@ export const RQKEY = () => ['app-passwords']
|
||||
export function useAppPasswordsQuery() {
|
||||
return useQuery({
|
||||
staleTime: STALE.MINUTES.FIVE,
|
||||
refetchInterval: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(),
|
||||
queryFn: async () => {
|
||||
const res = await getAgent().com.atproto.server.listAppPasswords({})
|
||||
|
||||
@@ -16,7 +16,6 @@ export type InviteCodesQueryResponse = Exclude<
|
||||
export function useInviteCodesQuery() {
|
||||
return useQuery({
|
||||
staleTime: STALE.MINUTES.FIVE,
|
||||
refetchInterval: STALE.MINUTES.FIVE,
|
||||
queryKey: ['inviteCodes'],
|
||||
queryFn: async () => {
|
||||
const res = await getAgent()
|
||||
|
||||
@@ -15,6 +15,7 @@ import {useMutedThreads} from '#/state/muted-threads'
|
||||
import {RQKEY as RQKEY_NOTIFS} from './feed'
|
||||
import {logger} from '#/logger'
|
||||
import {truncateAndInvalidate} from '../util'
|
||||
import {AppState} from 'react-native'
|
||||
|
||||
const UPDATE_INTERVAL = 30 * 1e3 // 30sec
|
||||
|
||||
@@ -97,6 +98,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
async checkUnread({invalidate}: {invalidate?: boolean} = {}) {
|
||||
try {
|
||||
if (!getAgent().session) return
|
||||
if (AppState.currentState !== 'active') {
|
||||
return
|
||||
}
|
||||
|
||||
// count
|
||||
const page = await fetchPage({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, {useCallback, useEffect, useRef} from 'react'
|
||||
import {AppState} from 'react-native'
|
||||
import {AppBskyFeedDefs, AppBskyFeedPost, PostModeration} from '@atproto/api'
|
||||
import {
|
||||
useInfiniteQuery,
|
||||
@@ -312,6 +313,9 @@ export async function pollLatest(page: FeedPage | undefined) {
|
||||
if (!page) {
|
||||
return false
|
||||
}
|
||||
if (AppState.currentState !== 'active') {
|
||||
return
|
||||
}
|
||||
|
||||
logger.debug('usePostFeedQuery: pollLatest')
|
||||
const post = await page.api.peekLatest()
|
||||
|
||||
@@ -181,14 +181,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
|
||||
const createAccount = React.useCallback<ApiContext['createAccount']>(
|
||||
async ({service, email, password, handle, inviteCode}: any) => {
|
||||
logger.debug(
|
||||
`session: creating account`,
|
||||
{
|
||||
service,
|
||||
handle,
|
||||
},
|
||||
logger.DebugContext.session,
|
||||
)
|
||||
logger.info(`session: creating account`, {
|
||||
service,
|
||||
handle,
|
||||
})
|
||||
track('Try Create Account')
|
||||
|
||||
const agent = new BskyAgent({service})
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface ComposerOpts {
|
||||
onPost?: () => void
|
||||
quote?: ComposerOptsQuote
|
||||
mention?: string // handle of user to mention
|
||||
openPicker?: (pos: DOMRect | undefined) => void
|
||||
}
|
||||
|
||||
type StateContext = ComposerOpts | undefined
|
||||
|
||||
@@ -136,7 +136,13 @@ export async function submit({
|
||||
msg`Invite code not accepted. Check that you input it correctly and try again.`,
|
||||
)
|
||||
}
|
||||
logger.error('Failed to create account', {error: e})
|
||||
|
||||
if ([400, 429].includes(e.status)) {
|
||||
logger.warn('Failed to create account', {error: e})
|
||||
} else {
|
||||
logger.error(`Failed to create account (${e.status} status)`, {error: e})
|
||||
}
|
||||
|
||||
uiDispatch({type: 'set-processing', value: false})
|
||||
uiDispatch({type: 'set-error', value: cleanError(errMsg)})
|
||||
throw e
|
||||
|
||||
@@ -107,17 +107,21 @@ export const LoginForm = ({
|
||||
})
|
||||
} catch (e: any) {
|
||||
const errMsg = e.toString()
|
||||
logger.warn('Failed to login', {error: e})
|
||||
setIsProcessing(false)
|
||||
if (errMsg.includes('Authentication Required')) {
|
||||
logger.info('Failed to login due to invalid credentials', {
|
||||
error: errMsg,
|
||||
})
|
||||
setError(_(msg`Invalid username or password`))
|
||||
} else if (isNetworkError(e)) {
|
||||
logger.warn('Failed to login due to network error', {error: errMsg})
|
||||
setError(
|
||||
_(
|
||||
msg`Unable to contact your service. Please check your Internet connection.`,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
logger.warn('Failed to login', {error: errMsg})
|
||||
setError(cleanError(errMsg))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
@@ -46,7 +47,6 @@ import {Gallery} from './photos/Gallery'
|
||||
import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
|
||||
import {LabelsBtn} from './labels/LabelsBtn'
|
||||
import {SelectLangBtn} from './select-language/SelectLangBtn'
|
||||
import {EmojiPickerButton} from './text-input/web/EmojiPicker.web'
|
||||
import {insertMentionAt} from 'lib/strings/mention-manip'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -70,6 +70,7 @@ export const ComposePost = observer(function ComposePost({
|
||||
onPost,
|
||||
quote: initQuote,
|
||||
mention: initMention,
|
||||
openPicker,
|
||||
}: Props) {
|
||||
const {currentAccount} = useSession()
|
||||
const {data: currentProfile} = useProfileQuery({did: currentAccount!.did})
|
||||
@@ -274,6 +275,10 @@ export const ComposePost = observer(function ComposePost({
|
||||
const canSelectImages = useMemo(() => gallery.size < 4, [gallery.size])
|
||||
const hasMedia = gallery.size > 0 || Boolean(extLink)
|
||||
|
||||
const onEmojiButtonPress = useCallback(() => {
|
||||
openPicker?.(textInput.current?.getCursorPosition())
|
||||
}, [openPicker])
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
testID="composePostView"
|
||||
@@ -456,7 +461,19 @@ export const ComposePost = observer(function ComposePost({
|
||||
<OpenCameraBtn gallery={gallery} />
|
||||
</>
|
||||
) : null}
|
||||
{!isMobile ? <EmojiPickerButton /> : null}
|
||||
{!isMobile ? (
|
||||
<Pressable
|
||||
onPress={onEmojiButtonPress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Open emoji picker`)}
|
||||
accessibilityHint={_(msg`Open emoji picker`)}>
|
||||
<FontAwesomeIcon
|
||||
icon={['far', 'face-smile']}
|
||||
color={pal.colors.link}
|
||||
size={22}
|
||||
/>
|
||||
</Pressable>
|
||||
) : null}
|
||||
<View style={s.flex1} />
|
||||
<SelectLangBtn />
|
||||
<CharProgress count={graphemeLength} />
|
||||
|
||||
@@ -32,6 +32,7 @@ import {POST_IMG_MAX} from 'lib/constants'
|
||||
export interface TextInputRef {
|
||||
focus: () => void
|
||||
blur: () => void
|
||||
getCursorPosition: () => DOMRect | undefined
|
||||
}
|
||||
|
||||
interface TextInputProps extends ComponentProps<typeof RNTextInput> {
|
||||
@@ -74,6 +75,7 @@ export const TextInput = forwardRef(function TextInputImpl(
|
||||
blur: () => {
|
||||
textInput.current?.blur()
|
||||
},
|
||||
getCursorPosition: () => undefined, // Not implemented on native
|
||||
}))
|
||||
|
||||
const onChangeText = useCallback(
|
||||
|
||||
@@ -22,6 +22,7 @@ import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
|
||||
export interface TextInputRef {
|
||||
focus: () => void
|
||||
blur: () => void
|
||||
getCursorPosition: () => DOMRect | undefined
|
||||
}
|
||||
|
||||
interface TextInputProps {
|
||||
@@ -169,6 +170,10 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: () => {}, // TODO
|
||||
blur: () => {}, // TODO
|
||||
getCursorPosition: () => {
|
||||
const pos = editor?.state.selection.$anchor.pos
|
||||
return pos ? editor?.view.coordsAtPos(pos) : undefined
|
||||
},
|
||||
}))
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import React from 'react'
|
||||
import Picker from '@emoji-mart/react'
|
||||
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||
import {
|
||||
StyleSheet,
|
||||
TouchableWithoutFeedback,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {textInputWebEmitter} from '../TextInput.web'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useMediaQuery} from 'react-responsive'
|
||||
|
||||
const HEIGHT_OFFSET = 40
|
||||
const WIDTH_OFFSET = 100
|
||||
const PICKER_HEIGHT = 435 + HEIGHT_OFFSET
|
||||
const PICKER_WIDTH = 350 + WIDTH_OFFSET
|
||||
|
||||
export type Emoji = {
|
||||
aliases?: string[]
|
||||
@@ -18,59 +24,87 @@ export type Emoji = {
|
||||
unified: string
|
||||
}
|
||||
|
||||
export function EmojiPickerButton() {
|
||||
const pal = usePalette('default')
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const onOpenChange = (o: boolean) => {
|
||||
setOpen(o)
|
||||
}
|
||||
const close = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu.Root open={open} onOpenChange={onOpenChange}>
|
||||
<DropdownMenu.Trigger style={styles.trigger}>
|
||||
<FontAwesomeIcon
|
||||
icon={['far', 'face-smile']}
|
||||
color={pal.colors.link}
|
||||
size={22}
|
||||
/>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<EmojiPicker close={close} />
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
)
|
||||
export interface EmojiPickerState {
|
||||
isOpen: boolean
|
||||
pos: {top: number; left: number; right: number; bottom: number}
|
||||
}
|
||||
|
||||
export function EmojiPicker({close}: {close: () => void}) {
|
||||
interface IProps {
|
||||
state: EmojiPickerState
|
||||
close: () => void
|
||||
}
|
||||
|
||||
export function EmojiPicker({state, close}: IProps) {
|
||||
const {height, width} = useWindowDimensions()
|
||||
|
||||
const isShiftDown = React.useRef(false)
|
||||
|
||||
const position = React.useMemo(() => {
|
||||
const fitsBelow = state.pos.top + PICKER_HEIGHT < height
|
||||
const fitsAbove = PICKER_HEIGHT < state.pos.top
|
||||
const placeOnLeft = PICKER_WIDTH < state.pos.left
|
||||
const screenYMiddle = height / 2 - PICKER_HEIGHT / 2
|
||||
|
||||
if (fitsBelow) {
|
||||
return {
|
||||
top: state.pos.top + HEIGHT_OFFSET,
|
||||
}
|
||||
} else if (fitsAbove) {
|
||||
return {
|
||||
bottom: height - state.pos.bottom + HEIGHT_OFFSET,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
top: screenYMiddle,
|
||||
left: placeOnLeft ? state.pos.left - PICKER_WIDTH : undefined,
|
||||
right: !placeOnLeft
|
||||
? width - state.pos.right - PICKER_WIDTH
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
}, [state.pos, height, width])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!state.isOpen) return
|
||||
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Shift') {
|
||||
isShiftDown.current = true
|
||||
}
|
||||
}
|
||||
const onKeyUp = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Shift') {
|
||||
isShiftDown.current = false
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', onKeyDown, true)
|
||||
window.addEventListener('keyup', onKeyUp, true)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', onKeyDown, true)
|
||||
window.removeEventListener('keyup', onKeyUp, true)
|
||||
}
|
||||
}, [state.isOpen])
|
||||
|
||||
const onInsert = (emoji: Emoji) => {
|
||||
textInputWebEmitter.emit('emoji-inserted', emoji)
|
||||
close()
|
||||
|
||||
if (!isShiftDown.current) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
const reducedPadding = useMediaQuery({query: '(max-height: 750px)'})
|
||||
const noPadding = useMediaQuery({query: '(max-height: 550px)'})
|
||||
const noPicker = useMediaQuery({query: '(max-height: 350px)'})
|
||||
|
||||
if (!state.isOpen) return null
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors
|
||||
<TouchableWithoutFeedback onPress={close} accessibilityViewIsModal>
|
||||
<TouchableWithoutFeedback
|
||||
accessibilityRole="button"
|
||||
onPress={close}
|
||||
accessibilityViewIsModal>
|
||||
<View style={styles.mask}>
|
||||
{/* eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors */}
|
||||
<TouchableWithoutFeedback
|
||||
onPress={e => {
|
||||
e.stopPropagation() // prevent event from bubbling up to the mask
|
||||
}}>
|
||||
<View
|
||||
style={[
|
||||
styles.picker,
|
||||
{
|
||||
paddingTop: noPadding ? 0 : reducedPadding ? 150 : 325,
|
||||
display: noPicker ? 'none' : 'flex',
|
||||
},
|
||||
]}>
|
||||
<TouchableWithoutFeedback onPress={e => e.stopPropagation()}>
|
||||
<View style={[{position: 'absolute'}, position]}>
|
||||
<Picker
|
||||
data={async () => {
|
||||
return (await import('./EmojiPickerData.json')).default
|
||||
@@ -93,15 +127,7 @@ const styles = StyleSheet.create({
|
||||
right: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
trigger: {
|
||||
backgroundColor: 'transparent',
|
||||
// @ts-ignore web only -prf
|
||||
border: 'none',
|
||||
paddingTop: 4,
|
||||
paddingLeft: 12,
|
||||
paddingRight: 12,
|
||||
cursor: 'pointer',
|
||||
alignItems: 'center',
|
||||
},
|
||||
picker: {
|
||||
marginHorizontal: 'auto',
|
||||
|
||||
@@ -229,7 +229,7 @@ export function FeedSourceCardLoaded({
|
||||
</View>
|
||||
|
||||
{showSaveBtn && feed.type === 'feed' && (
|
||||
<View>
|
||||
<View style={[s.justifyCenter]}>
|
||||
<Pressable
|
||||
testID={`feed-${feed.displayName}-toggleSave`}
|
||||
disabled={isSavePending || isPinPending || isRemovePending}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import React, {useMemo, useCallback, useState} from 'react'
|
||||
import {
|
||||
ImageStyle,
|
||||
KeyboardAvoidingView,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native'
|
||||
import {ScrollView, TextInput} from './util'
|
||||
import {Image} from 'expo-image'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {gradients, s} from 'lib/styles'
|
||||
@@ -17,13 +15,13 @@ import {MAX_ALT_TEXT} from 'lib/constants'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {Text} from '../util/text/Text'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import {isAndroid, isWeb} from 'platform/detection'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {ImageModel} from 'state/models/media/image'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
|
||||
export const snapPoints = ['fullscreen']
|
||||
export const snapPoints = ['100%']
|
||||
|
||||
interface Props {
|
||||
image: ImageModel
|
||||
@@ -54,102 +52,86 @@ export function Component({image}: Props) {
|
||||
}
|
||||
}, [image, windim])
|
||||
|
||||
const onUpdate = useCallback(
|
||||
(v: string) => {
|
||||
v = enforceLen(v, MAX_ALT_TEXT)
|
||||
setAltText(v)
|
||||
image.setAltText(v)
|
||||
},
|
||||
[setAltText, image],
|
||||
)
|
||||
|
||||
const onPressSave = useCallback(() => {
|
||||
image.setAltText(altText)
|
||||
closeModal()
|
||||
}, [closeModal, image, altText])
|
||||
|
||||
const onPressCancel = () => {
|
||||
closeModal()
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
behavior={isAndroid ? 'height' : 'padding'}
|
||||
style={[pal.view, styles.container]}>
|
||||
<ScrollView
|
||||
testID="altTextImageModal"
|
||||
style={styles.scrollContainer}
|
||||
keyboardShouldPersistTaps="always"
|
||||
nativeID="imageAltText">
|
||||
<View style={styles.scrollInner}>
|
||||
<View style={[pal.viewLight, styles.imageContainer]}>
|
||||
<Image
|
||||
testID="selectedPhotoImage"
|
||||
style={imageStyles}
|
||||
source={{
|
||||
uri: image.cropped?.path ?? image.path,
|
||||
}}
|
||||
contentFit="contain"
|
||||
accessible={true}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
</View>
|
||||
<TextInput
|
||||
testID="altTextImageInput"
|
||||
style={[styles.textArea, pal.border, pal.text]}
|
||||
keyboardAppearance={theme.colorScheme}
|
||||
multiline
|
||||
placeholder="Add alt text"
|
||||
placeholderTextColor={pal.colors.textLight}
|
||||
value={altText}
|
||||
onChangeText={text => setAltText(enforceLen(text, MAX_ALT_TEXT))}
|
||||
accessibilityLabel={_(msg`Image alt text`)}
|
||||
accessibilityHint=""
|
||||
accessibilityLabelledBy="imageAltText"
|
||||
autoFocus
|
||||
<ScrollView
|
||||
testID="altTextImageModal"
|
||||
style={[pal.view, styles.scrollContainer]}
|
||||
keyboardShouldPersistTaps="always"
|
||||
nativeID="imageAltText">
|
||||
<View style={styles.scrollInner}>
|
||||
<View style={[pal.viewLight, styles.imageContainer]}>
|
||||
<Image
|
||||
testID="selectedPhotoImage"
|
||||
style={imageStyles}
|
||||
source={{
|
||||
uri: image.cropped?.path ?? image.path,
|
||||
}}
|
||||
contentFit="contain"
|
||||
accessible={true}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
<View style={styles.buttonControls}>
|
||||
<TouchableOpacity
|
||||
testID="altTextImageSaveBtn"
|
||||
onPress={onPressSave}
|
||||
accessibilityLabel={_(msg`Save alt text`)}
|
||||
accessibilityHint={`Saves alt text, which reads: ${altText}`}
|
||||
accessibilityRole="button">
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
style={[styles.button]}>
|
||||
<Text type="button-lg" style={[s.white, s.bold]}>
|
||||
<Trans>Save</Trans>
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
testID="altTextImageCancelBtn"
|
||||
onPress={onPressCancel}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Cancel add image alt text`)}
|
||||
accessibilityHint=""
|
||||
onAccessibilityEscape={onPressCancel}>
|
||||
<View style={[styles.button]}>
|
||||
<Text type="button-lg" style={[pal.textLight]}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
<TextInput
|
||||
testID="altTextImageInput"
|
||||
style={[styles.textArea, pal.border, pal.text]}
|
||||
keyboardAppearance={theme.colorScheme}
|
||||
multiline
|
||||
placeholder={_(msg`Add alt text`)}
|
||||
placeholderTextColor={pal.colors.textLight}
|
||||
value={altText}
|
||||
onChangeText={onUpdate}
|
||||
accessibilityLabel={_(msg`Image alt text`)}
|
||||
accessibilityHint=""
|
||||
accessibilityLabelledBy="imageAltText"
|
||||
autoFocus
|
||||
/>
|
||||
<View style={styles.buttonControls}>
|
||||
<TouchableOpacity
|
||||
testID="altTextImageSaveBtn"
|
||||
onPress={onPressSave}
|
||||
accessibilityLabel={_(msg`Save alt text`)}
|
||||
accessibilityHint=""
|
||||
accessibilityRole="button">
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
style={[styles.button]}>
|
||||
<Text type="button-lg" style={[s.white, s.bold]}>
|
||||
<Trans>Done</Trans>
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
paddingVertical: isWeb ? 0 : 18,
|
||||
},
|
||||
scrollContainer: {
|
||||
flex: 1,
|
||||
height: '100%',
|
||||
paddingHorizontal: isWeb ? 0 : 12,
|
||||
paddingVertical: isWeb ? 0 : 24,
|
||||
},
|
||||
scrollInner: {
|
||||
gap: 12,
|
||||
paddingTop: isWeb ? 0 : 12,
|
||||
},
|
||||
imageContainer: {
|
||||
borderRadius: 8,
|
||||
@@ -173,5 +155,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
buttonControls: {
|
||||
gap: 8,
|
||||
paddingBottom: isWeb ? 0 : 50,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
import React from 'react'
|
||||
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import {s, colors, gradients} from 'lib/styles'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {ScrollView} from './util'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {
|
||||
EmbedPlayerSource,
|
||||
embedPlayerSources,
|
||||
externalEmbedLabels,
|
||||
} from '#/lib/strings/embed-player'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useSetExternalEmbedPref} from '#/state/preferences/external-embeds-prefs'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
|
||||
export const snapPoints = [450]
|
||||
|
||||
export function Component({
|
||||
onAccept,
|
||||
source,
|
||||
}: {
|
||||
onAccept: () => void
|
||||
source: EmbedPlayerSource
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {closeModal} = useModalControls()
|
||||
const {_} = useLingui()
|
||||
const setExternalEmbedPref = useSetExternalEmbedPref()
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
|
||||
const onShowAllPress = React.useCallback(() => {
|
||||
for (const key of embedPlayerSources) {
|
||||
setExternalEmbedPref(key, 'show')
|
||||
}
|
||||
onAccept()
|
||||
closeModal()
|
||||
}, [closeModal, onAccept, setExternalEmbedPref])
|
||||
|
||||
const onShowPress = React.useCallback(() => {
|
||||
setExternalEmbedPref(source, 'show')
|
||||
onAccept()
|
||||
closeModal()
|
||||
}, [closeModal, onAccept, setExternalEmbedPref, source])
|
||||
|
||||
const onHidePress = React.useCallback(() => {
|
||||
setExternalEmbedPref(source, 'hide')
|
||||
closeModal()
|
||||
}, [closeModal, setExternalEmbedPref, source])
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
testID="embedConsentModal"
|
||||
style={[
|
||||
s.flex1,
|
||||
pal.view,
|
||||
isMobile
|
||||
? {paddingHorizontal: 20, paddingTop: 10}
|
||||
: {paddingHorizontal: 30},
|
||||
]}>
|
||||
<Text style={[pal.text, styles.title]}>
|
||||
<Trans>External Media</Trans>
|
||||
</Text>
|
||||
|
||||
<Text style={pal.text}>
|
||||
<Trans>
|
||||
This content is hosted by {externalEmbedLabels[source]}. Do you want
|
||||
to enable external media?
|
||||
</Trans>
|
||||
</Text>
|
||||
<View style={[s.mt10]} />
|
||||
<Text style={pal.textLight}>
|
||||
<Trans>
|
||||
External media may allow websites to collect information about you and
|
||||
your device. No information is sent or requested until you press the
|
||||
"play" button.
|
||||
</Trans>
|
||||
</Text>
|
||||
<View style={[s.mt20]} />
|
||||
<TouchableOpacity
|
||||
testID="enableAllBtn"
|
||||
onPress={onShowAllPress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(
|
||||
msg`Show embeds from ${externalEmbedLabels[source]}`,
|
||||
)}
|
||||
accessibilityHint=""
|
||||
onAccessibilityEscape={closeModal}>
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
style={[styles.btn]}>
|
||||
<Text style={[s.white, s.bold, s.f18]}>
|
||||
<Trans>Enable External Media</Trans>
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
<View style={[s.mt10]} />
|
||||
<TouchableOpacity
|
||||
testID="enableSourceBtn"
|
||||
onPress={onShowPress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(
|
||||
msg`Never load embeds from ${externalEmbedLabels[source]}`,
|
||||
)}
|
||||
accessibilityHint=""
|
||||
onAccessibilityEscape={closeModal}>
|
||||
<View style={[styles.btn, pal.btn]}>
|
||||
<Text style={[pal.text, s.bold, s.f18]}>
|
||||
<Trans>Enable {externalEmbedLabels[source]} only</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<View style={[s.mt10]} />
|
||||
<TouchableOpacity
|
||||
testID="disableSourceBtn"
|
||||
onPress={onHidePress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(
|
||||
msg`Never load embeds from ${externalEmbedLabels[source]}`,
|
||||
)}
|
||||
accessibilityHint=""
|
||||
onAccessibilityEscape={closeModal}>
|
||||
<View style={[styles.btn, pal.btn]}>
|
||||
<Text style={[pal.text, s.bold, s.f18]}>
|
||||
<Trans>No thanks</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
title: {
|
||||
textAlign: 'center',
|
||||
fontWeight: 'bold',
|
||||
fontSize: 24,
|
||||
marginBottom: 12,
|
||||
},
|
||||
btn: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
borderRadius: 32,
|
||||
padding: 14,
|
||||
backgroundColor: colors.gray1,
|
||||
},
|
||||
})
|
||||
@@ -38,6 +38,7 @@ import * as VerifyEmailModal from './VerifyEmail'
|
||||
import * as ChangeEmailModal from './ChangeEmail'
|
||||
import * as SwitchAccountModal from './SwitchAccount'
|
||||
import * as LinkWarningModal from './LinkWarning'
|
||||
import * as EmbedConsentModal from './EmbedConsent'
|
||||
|
||||
const DEFAULT_SNAPPOINTS = ['90%']
|
||||
const HANDLE_HEIGHT = 24
|
||||
@@ -176,6 +177,9 @@ export function ModalsContainer() {
|
||||
} else if (activeModal?.name === 'link-warning') {
|
||||
snapPoints = LinkWarningModal.snapPoints
|
||||
element = <LinkWarningModal.Component {...activeModal} />
|
||||
} else if (activeModal?.name === 'embed-consent') {
|
||||
snapPoints = EmbedConsentModal.snapPoints
|
||||
element = <EmbedConsentModal.Component {...activeModal} />
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import * as BirthDateSettingsModal from './BirthDateSettings'
|
||||
import * as VerifyEmailModal from './VerifyEmail'
|
||||
import * as ChangeEmailModal from './ChangeEmail'
|
||||
import * as LinkWarningModal from './LinkWarning'
|
||||
import * as EmbedConsentModal from './EmbedConsent'
|
||||
|
||||
export function ModalsContainer() {
|
||||
const {isModalActive, activeModals} = useModals()
|
||||
@@ -129,6 +130,8 @@ function Modal({modal}: {modal: ModalIface}) {
|
||||
element = <ChangeEmailModal.Component />
|
||||
} else if (modal.name === 'link-warning') {
|
||||
element = <LinkWarningModal.Component {...modal} />
|
||||
} else if (modal.name === 'embed-consent') {
|
||||
element = <EmbedConsentModal.Component {...modal} />
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
import {EmbedPlayerParams, getGifDims} from 'lib/strings/embed-player'
|
||||
import React from 'react'
|
||||
import {Image, ImageLoadEventData} from 'expo-image'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
GestureResponderEvent,
|
||||
LayoutChangeEvent,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {useExternalEmbedsPrefs} from 'state/preferences'
|
||||
import {useModalControls} from 'state/modals'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {AppBskyEmbedExternal} from '@atproto/api'
|
||||
|
||||
export function ExternalGifEmbed({
|
||||
link,
|
||||
params,
|
||||
}: {
|
||||
link: AppBskyEmbedExternal.ViewExternal
|
||||
params: EmbedPlayerParams
|
||||
}) {
|
||||
const externalEmbedsPrefs = useExternalEmbedsPrefs()
|
||||
const {openModal} = useModalControls()
|
||||
const {_} = useLingui()
|
||||
|
||||
const thumbHasLoaded = React.useRef(false)
|
||||
const viewWidth = React.useRef(0)
|
||||
|
||||
// Tracking if the placer has been activated
|
||||
const [isPlayerActive, setIsPlayerActive] = React.useState(false)
|
||||
// Tracking whether the gif has been loaded yet
|
||||
const [isPrefetched, setIsPrefetched] = React.useState(false)
|
||||
// Tracking whether the image is animating
|
||||
const [isAnimating, setIsAnimating] = React.useState(true)
|
||||
const [imageDims, setImageDims] = React.useState({height: 100, width: 1})
|
||||
|
||||
// Used for controlling animation
|
||||
const imageRef = React.useRef<Image>(null)
|
||||
|
||||
const load = React.useCallback(() => {
|
||||
setIsPlayerActive(true)
|
||||
Image.prefetch(params.playerUri).then(() => {
|
||||
// Replace the image once it's fetched
|
||||
setIsPrefetched(true)
|
||||
})
|
||||
}, [params.playerUri])
|
||||
|
||||
const onPlayPress = React.useCallback(
|
||||
(event: GestureResponderEvent) => {
|
||||
// Don't propagate on web
|
||||
event.preventDefault()
|
||||
|
||||
// Show consent if this is the first load
|
||||
if (externalEmbedsPrefs?.[params.source] === undefined) {
|
||||
openModal({
|
||||
name: 'embed-consent',
|
||||
source: params.source,
|
||||
onAccept: load,
|
||||
})
|
||||
return
|
||||
}
|
||||
// If the player isn't active, we want to activate it and prefetch the gif
|
||||
if (!isPlayerActive) {
|
||||
load()
|
||||
return
|
||||
}
|
||||
// Control animation on native
|
||||
setIsAnimating(prev => {
|
||||
if (prev) {
|
||||
if (isNative) {
|
||||
imageRef.current?.stopAnimating()
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
if (isNative) {
|
||||
imageRef.current?.startAnimating()
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
},
|
||||
[externalEmbedsPrefs, isPlayerActive, load, openModal, params.source],
|
||||
)
|
||||
|
||||
const onLoad = React.useCallback((e: ImageLoadEventData) => {
|
||||
if (thumbHasLoaded.current) return
|
||||
setImageDims(getGifDims(e.source.height, e.source.width, viewWidth.current))
|
||||
thumbHasLoaded.current = true
|
||||
}, [])
|
||||
|
||||
const onLayout = React.useCallback((e: LayoutChangeEvent) => {
|
||||
viewWidth.current = e.nativeEvent.layout.width
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={[
|
||||
{height: imageDims.height},
|
||||
styles.topRadius,
|
||||
styles.gifContainer,
|
||||
]}
|
||||
onPress={onPlayPress}
|
||||
onLayout={onLayout}
|
||||
accessibilityRole="button"
|
||||
accessibilityHint={_(msg`Plays the GIF`)}
|
||||
accessibilityLabel={_(msg`Play ${link.title}`)}>
|
||||
{(!isPrefetched || !isAnimating) && ( // If we have not loaded or are not animating, show the overlay
|
||||
<View style={[styles.layer, styles.overlayLayer]}>
|
||||
<View style={[styles.overlayContainer, styles.topRadius]}>
|
||||
{!isAnimating || !isPlayerActive ? ( // Play button when not animating or not active
|
||||
<FontAwesomeIcon icon="play" size={42} color="white" />
|
||||
) : (
|
||||
// Activity indicator while gif loads
|
||||
<ActivityIndicator size="large" color="white" />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
!isPrefetched || (isWeb && !isAnimating)
|
||||
? link.thumb
|
||||
: params.playerUri,
|
||||
}} // Web uses the thumb to control playback
|
||||
style={{flex: 1}}
|
||||
ref={imageRef}
|
||||
onLoad={onLoad}
|
||||
autoplay={isAnimating}
|
||||
contentFit="contain"
|
||||
accessibilityIgnoresInvertColors
|
||||
accessibilityLabel={link.title}
|
||||
accessibilityHint={link.title}
|
||||
cachePolicy={isIOS ? 'disk' : 'memory-disk'} // cant control playback with memory-disk on ios
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
topRadius: {
|
||||
borderTopLeftRadius: 6,
|
||||
borderTopRightRadius: 6,
|
||||
},
|
||||
layer: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
overlayContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
},
|
||||
overlayLayer: {
|
||||
zIndex: 2,
|
||||
},
|
||||
gifContainer: {
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
})
|
||||
@@ -8,6 +8,8 @@ import {AppBskyEmbedExternal} from '@atproto/api'
|
||||
import {toNiceDomain} from 'lib/strings/url-helpers'
|
||||
import {parseEmbedPlayerFromUrl} from 'lib/strings/embed-player'
|
||||
import {ExternalPlayer} from 'view/com/util/post-embeds/ExternalPlayerEmbed'
|
||||
import {ExternalGifEmbed} from 'view/com/util/post-embeds/ExternalGifEmbed'
|
||||
import {useExternalEmbedsPrefs} from 'state/preferences'
|
||||
|
||||
export const ExternalLinkEmbed = ({
|
||||
link,
|
||||
@@ -16,36 +18,27 @@ export const ExternalLinkEmbed = ({
|
||||
}) => {
|
||||
const pal = usePalette('default')
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
const externalEmbedPrefs = useExternalEmbedsPrefs()
|
||||
|
||||
const embedPlayerParams = React.useMemo(
|
||||
() => parseEmbedPlayerFromUrl(link.uri),
|
||||
[link.uri],
|
||||
)
|
||||
const embedPlayerParams = React.useMemo(() => {
|
||||
const params = parseEmbedPlayerFromUrl(link.uri)
|
||||
|
||||
if (params && externalEmbedPrefs?.[params.source] !== 'hide') {
|
||||
return params
|
||||
}
|
||||
}, [link.uri, externalEmbedPrefs])
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: !isMobile && !embedPlayerParams ? 'row' : 'column',
|
||||
}}>
|
||||
<View style={{flexDirection: 'column'}}>
|
||||
{link.thumb && !embedPlayerParams ? (
|
||||
<View
|
||||
style={
|
||||
!isMobile
|
||||
? {
|
||||
borderTopLeftRadius: 6,
|
||||
borderBottomLeftRadius: 6,
|
||||
width: 120,
|
||||
aspectRatio: 1,
|
||||
overflow: 'hidden',
|
||||
}
|
||||
: {
|
||||
borderTopLeftRadius: 6,
|
||||
borderTopRightRadius: 6,
|
||||
width: '100%',
|
||||
height: 200,
|
||||
overflow: 'hidden',
|
||||
}
|
||||
}>
|
||||
style={{
|
||||
borderTopLeftRadius: 6,
|
||||
borderTopRightRadius: 6,
|
||||
width: '100%',
|
||||
height: isMobile ? 200 : 300,
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<Image
|
||||
style={styles.extImage}
|
||||
source={{uri: link.thumb}}
|
||||
@@ -53,15 +46,17 @@ export const ExternalLinkEmbed = ({
|
||||
/>
|
||||
</View>
|
||||
) : undefined}
|
||||
{embedPlayerParams && (
|
||||
<ExternalPlayer link={link} params={embedPlayerParams} />
|
||||
)}
|
||||
{(embedPlayerParams?.isGif && (
|
||||
<ExternalGifEmbed link={link} params={embedPlayerParams} />
|
||||
)) ||
|
||||
(embedPlayerParams && (
|
||||
<ExternalPlayer link={link} params={embedPlayerParams} />
|
||||
))}
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: isMobile ? 10 : 14,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 10,
|
||||
flex: !isMobile ? 1 : undefined,
|
||||
}}>
|
||||
<Text
|
||||
type="sm"
|
||||
@@ -69,16 +64,15 @@ export const ExternalLinkEmbed = ({
|
||||
style={[pal.textLight, styles.extUri]}>
|
||||
{toNiceDomain(link.uri)}
|
||||
</Text>
|
||||
<Text
|
||||
type="lg-bold"
|
||||
numberOfLines={isMobile ? 4 : 2}
|
||||
style={[pal.text]}>
|
||||
{link.title || link.uri}
|
||||
</Text>
|
||||
{link.description ? (
|
||||
{!embedPlayerParams?.isGif && (
|
||||
<Text type="lg-bold" numberOfLines={4} style={[pal.text]}>
|
||||
{link.title || link.uri}
|
||||
</Text>
|
||||
)}
|
||||
{link.description && !embedPlayerParams?.hideDetails ? (
|
||||
<Text
|
||||
type="md"
|
||||
numberOfLines={isMobile ? 4 : 2}
|
||||
numberOfLines={4}
|
||||
style={[pal.text, styles.extDescription]}>
|
||||
{link.description}
|
||||
</Text>
|
||||
@@ -90,8 +84,7 @@ export const ExternalLinkEmbed = ({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
extImage: {
|
||||
width: '100%',
|
||||
height: 200,
|
||||
flex: 1,
|
||||
},
|
||||
extUri: {
|
||||
marginTop: 2,
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Dimensions,
|
||||
GestureResponderEvent,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import Animated, {
|
||||
measure,
|
||||
runOnJS,
|
||||
useAnimatedRef,
|
||||
useFrameCallback,
|
||||
} from 'react-native-reanimated'
|
||||
import {Image} from 'expo-image'
|
||||
import {WebView} from 'react-native-webview'
|
||||
import YoutubePlayer from 'react-native-youtube-iframe'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {AppBskyEmbedExternal} from '@atproto/api'
|
||||
import {EmbedPlayerParams, getPlayerHeight} from 'lib/strings/embed-player'
|
||||
import {EventStopper} from '../EventStopper'
|
||||
import {AppBskyEmbedExternal} from '@atproto/api'
|
||||
import {isNative} from 'platform/detection'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {NavigationProp} from 'lib/routes/types'
|
||||
import {useExternalEmbedsPrefs} from 'state/preferences'
|
||||
import {useModalControls} from 'state/modals'
|
||||
|
||||
interface ShouldStartLoadRequest {
|
||||
url: string
|
||||
@@ -32,6 +42,8 @@ function PlaceholderOverlay({
|
||||
isPlayerActive: boolean
|
||||
onPress: (event: GestureResponderEvent) => void
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
|
||||
// If the player is active and not loading, we don't want to show the overlay.
|
||||
if (isPlayerActive && !isLoading) return null
|
||||
|
||||
@@ -39,8 +51,8 @@ function PlaceholderOverlay({
|
||||
<View style={[styles.layer, styles.overlayLayer]}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Play Video"
|
||||
accessibilityHint=""
|
||||
accessibilityLabel={_(msg`Play Video`)}
|
||||
accessibilityHint={_(msg`Play Video`)}
|
||||
onPress={onPress}
|
||||
style={[styles.overlayContainer, styles.topRadius]}>
|
||||
{!isPlayerActive ? (
|
||||
@@ -77,31 +89,21 @@ function Player({
|
||||
return (
|
||||
<View style={[styles.layer, styles.playerLayer]}>
|
||||
<EventStopper>
|
||||
{isNative && params.type === 'youtube_video' ? (
|
||||
<YoutubePlayer
|
||||
videoId={params.videoId}
|
||||
play
|
||||
height={height}
|
||||
onReady={onLoad}
|
||||
webViewStyle={[styles.webview, styles.topRadius]}
|
||||
<View style={{height, width: '100%'}}>
|
||||
<WebView
|
||||
javaScriptEnabled={true}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
mediaPlaybackRequiresUserAction={false}
|
||||
allowsInlineMediaPlayback
|
||||
bounces={false}
|
||||
allowsFullscreenVideo
|
||||
nestedScrollEnabled
|
||||
source={{uri: params.playerUri}}
|
||||
onLoad={onLoad}
|
||||
setSupportMultipleWindows={false} // Prevent any redirects from opening a new window (ads)
|
||||
style={[styles.webview, styles.topRadius]}
|
||||
/>
|
||||
) : (
|
||||
<View style={{height, width: '100%'}}>
|
||||
<WebView
|
||||
javaScriptEnabled={true}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
mediaPlaybackRequiresUserAction={false}
|
||||
allowsInlineMediaPlayback
|
||||
bounces={false}
|
||||
allowsFullscreenVideo
|
||||
nestedScrollEnabled
|
||||
source={{uri: params.playerUri}}
|
||||
onLoad={onLoad}
|
||||
setSupportMultipleWindows={false} // Prevent any redirects from opening a new window (ads)
|
||||
style={[styles.webview, styles.topRadius]}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</EventStopper>
|
||||
</View>
|
||||
)
|
||||
@@ -116,6 +118,10 @@ export function ExternalPlayer({
|
||||
params: EmbedPlayerParams
|
||||
}) {
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const insets = useSafeAreaInsets()
|
||||
const windowDims = useWindowDimensions()
|
||||
const externalEmbedsPrefs = useExternalEmbedsPrefs()
|
||||
const {openModal} = useModalControls()
|
||||
|
||||
const [isPlayerActive, setPlayerActive] = React.useState(false)
|
||||
const [isLoading, setIsLoading] = React.useState(true)
|
||||
@@ -124,34 +130,51 @@ export function ExternalPlayer({
|
||||
height: 0,
|
||||
})
|
||||
|
||||
const viewRef = React.useRef<View>(null)
|
||||
const viewRef = useAnimatedRef()
|
||||
|
||||
const frameCallback = useFrameCallback(() => {
|
||||
const measurement = measure(viewRef)
|
||||
if (!measurement) return
|
||||
|
||||
const {height: winHeight, width: winWidth} = windowDims
|
||||
|
||||
// Get the proper screen height depending on what is going on
|
||||
const realWinHeight = isNative // If it is native, we always want the larger number
|
||||
? winHeight > winWidth
|
||||
? winHeight
|
||||
: winWidth
|
||||
: winHeight // On web, we always want the actual screen height
|
||||
|
||||
const top = measurement.pageY
|
||||
const bot = measurement.pageY + measurement.height
|
||||
|
||||
// We can use the same logic on all platforms against the screenHeight that we get above
|
||||
const isVisible = top <= realWinHeight - insets.bottom && bot >= insets.top
|
||||
|
||||
if (!isVisible) {
|
||||
runOnJS(setPlayerActive)(false)
|
||||
}
|
||||
}, false) // False here disables autostarting the callback
|
||||
|
||||
// watch for leaving the viewport due to scrolling
|
||||
React.useEffect(() => {
|
||||
// We don't want to do anything if the player isn't active
|
||||
if (!isPlayerActive) return
|
||||
|
||||
// Interval for scrolling works in most cases, However, for twitch embeds, if we navigate away from the screen the webview will
|
||||
// continue playing. We need to watch for the blur event
|
||||
const unsubscribe = navigation.addListener('blur', () => {
|
||||
setPlayerActive(false)
|
||||
})
|
||||
|
||||
const interval = setInterval(() => {
|
||||
viewRef.current?.measure((x, y, w, h, pageX, pageY) => {
|
||||
const window = Dimensions.get('window')
|
||||
const top = pageY
|
||||
const bot = pageY + h
|
||||
const isVisible = isNative
|
||||
? top >= 0 && bot <= window.height
|
||||
: !(top >= window.height || bot <= 0)
|
||||
if (!isVisible) {
|
||||
setPlayerActive(false)
|
||||
}
|
||||
})
|
||||
}, 1e3)
|
||||
// Start watching for changes
|
||||
frameCallback.setActive(true)
|
||||
|
||||
return () => {
|
||||
unsubscribe()
|
||||
clearInterval(interval)
|
||||
frameCallback.setActive(false)
|
||||
}
|
||||
}, [viewRef, navigation])
|
||||
}, [navigation, isPlayerActive, frameCallback])
|
||||
|
||||
// calculate height for the player and the screen size
|
||||
const height = React.useMemo(
|
||||
@@ -168,12 +191,26 @@ export function ExternalPlayer({
|
||||
setIsLoading(false)
|
||||
}, [])
|
||||
|
||||
const onPlayPress = React.useCallback((event: GestureResponderEvent) => {
|
||||
// Prevent this from propagating upward on web
|
||||
event.preventDefault()
|
||||
const onPlayPress = React.useCallback(
|
||||
(event: GestureResponderEvent) => {
|
||||
// Prevent this from propagating upward on web
|
||||
event.preventDefault()
|
||||
|
||||
setPlayerActive(true)
|
||||
}, [])
|
||||
if (externalEmbedsPrefs?.[params.source] === undefined) {
|
||||
openModal({
|
||||
name: 'embed-consent',
|
||||
source: params.source,
|
||||
onAccept: () => {
|
||||
setPlayerActive(true)
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
setPlayerActive(true)
|
||||
},
|
||||
[externalEmbedsPrefs, openModal, params.source],
|
||||
)
|
||||
|
||||
// measure the layout to set sizing
|
||||
const onLayout = React.useCallback(
|
||||
@@ -187,7 +224,7 @@ export function ExternalPlayer({
|
||||
)
|
||||
|
||||
return (
|
||||
<View
|
||||
<Animated.View
|
||||
ref={viewRef}
|
||||
style={{height}}
|
||||
collapsable={false}
|
||||
@@ -205,7 +242,6 @@ export function ExternalPlayer({
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)}
|
||||
|
||||
<PlaceholderOverlay
|
||||
isLoading={isLoading}
|
||||
isPlayerActive={isPlayerActive}
|
||||
@@ -217,7 +253,7 @@ export function ExternalPlayer({
|
||||
height={height}
|
||||
onLoad={onLoad}
|
||||
/>
|
||||
</View>
|
||||
</Animated.View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -248,4 +284,8 @@ const styles = StyleSheet.create({
|
||||
webview: {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
gifContainer: {
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -98,6 +98,7 @@ export function QuoteEmbed({
|
||||
return (
|
||||
<Link
|
||||
style={[styles.container, pal.borderDark, style]}
|
||||
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
|
||||
href={itemHref}
|
||||
title={itemTitle}>
|
||||
<PostMeta
|
||||
|
||||
@@ -63,7 +63,7 @@ export function PostEmbeds({
|
||||
const mediaModeration = isModOnQuote ? {} : moderation
|
||||
const quoteModeration = isModOnQuote ? moderation : {}
|
||||
return (
|
||||
<View style={[styles.stackContainer, style]}>
|
||||
<View style={style}>
|
||||
<PostEmbeds embed={embed.media} moderation={mediaModeration} />
|
||||
<ContentHider moderation={quoteModeration}>
|
||||
<MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} />
|
||||
@@ -168,11 +168,14 @@ export function PostEmbeds({
|
||||
const link = embed.external
|
||||
|
||||
return (
|
||||
<View style={[styles.extOuter, pal.view, pal.border, style]}>
|
||||
<Link asAnchor href={link.uri}>
|
||||
<ExternalLinkEmbed link={link} />
|
||||
</Link>
|
||||
</View>
|
||||
<Link
|
||||
asAnchor
|
||||
anchorNoUnderline
|
||||
href={link.uri}
|
||||
style={[styles.extOuter, pal.view, pal.borderDark, style]}
|
||||
hoverStyle={{borderColor: pal.colors.borderLinkHover}}>
|
||||
<ExternalLinkEmbed link={link} />
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -180,9 +183,6 @@ export function PostEmbeds({
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
stackContainer: {
|
||||
gap: 6,
|
||||
},
|
||||
imagesContainer: {
|
||||
marginTop: 8,
|
||||
},
|
||||
|
||||
@@ -29,9 +29,10 @@ import {faChevronRight} from '@fortawesome/free-solid-svg-icons/faChevronRight'
|
||||
import {faCircle} from '@fortawesome/free-regular-svg-icons/faCircle'
|
||||
import {faCircleCheck as farCircleCheck} from '@fortawesome/free-regular-svg-icons/faCircleCheck'
|
||||
import {faCircleCheck} from '@fortawesome/free-solid-svg-icons/faCircleCheck'
|
||||
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons/faCircleExclamation'
|
||||
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
||||
import {faCircleDot} from '@fortawesome/free-solid-svg-icons/faCircleDot'
|
||||
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons/faCircleExclamation'
|
||||
import {faCirclePlay} from '@fortawesome/free-regular-svg-icons/faCirclePlay'
|
||||
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
||||
import {faClone} from '@fortawesome/free-solid-svg-icons/faClone'
|
||||
import {faClone as farClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
||||
import {faComment} from '@fortawesome/free-regular-svg-icons/faComment'
|
||||
@@ -129,9 +130,10 @@ library.add(
|
||||
faCircle,
|
||||
faCircleCheck,
|
||||
farCircleCheck,
|
||||
faCircleExclamation,
|
||||
faCircleUser,
|
||||
faCircleDot,
|
||||
faCircleExclamation,
|
||||
faCirclePlay,
|
||||
faCircleUser,
|
||||
faClone,
|
||||
farClone,
|
||||
faComment,
|
||||
|
||||
@@ -19,6 +19,7 @@ import {useSession} from '#/state/session'
|
||||
import {loadString, saveString} from '#/lib/storage'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {PROD_DEFAULT_FEED} from '#/lib/constants'
|
||||
|
||||
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
||||
export function HomeScreen(props: Props) {
|
||||
@@ -109,7 +110,9 @@ function HomeScreenReady({
|
||||
const homeFeedParams = React.useMemo<FeedParams>(() => {
|
||||
return {
|
||||
mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled),
|
||||
mergeFeedSources: preferences.feeds.saved,
|
||||
mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled
|
||||
? preferences.feeds.saved
|
||||
: [PROD_DEFAULT_FEED('whats-hot')],
|
||||
}
|
||||
}, [preferences])
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export function ModerationScreen({}: Props) {
|
||||
]}
|
||||
testID="moderationScreen">
|
||||
<ViewHeader title={_(msg`Moderation`)} showOnDesktop />
|
||||
<ScrollView>
|
||||
<ScrollView contentContainerStyle={[styles.noBorder]}>
|
||||
<View style={styles.spacer} />
|
||||
<TouchableOpacity
|
||||
testID="contentFilteringBtn"
|
||||
@@ -275,4 +275,10 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 30,
|
||||
marginRight: 12,
|
||||
},
|
||||
noBorder: {
|
||||
borderBottomWidth: 0,
|
||||
borderRightWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderTopWidth: 0,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import React from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||
import {s} from 'lib/styles'
|
||||
import {Text} from '../com/util/text/Text'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {
|
||||
EmbedPlayerSource,
|
||||
externalEmbedLabels,
|
||||
} from '#/lib/strings/embed-player'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {ScrollView} from '../com/util/Views'
|
||||
import {
|
||||
useExternalEmbedsPrefs,
|
||||
useSetExternalEmbedPref,
|
||||
} from 'state/preferences'
|
||||
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
|
||||
import {SimpleViewHeader} from '../com/util/SimpleViewHeader'
|
||||
|
||||
type Props = NativeStackScreenProps<
|
||||
CommonNavigatorParams,
|
||||
'PreferencesExternalEmbeds'
|
||||
>
|
||||
export function PreferencesExternalEmbeds({}: Props) {
|
||||
const pal = usePalette('default')
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {screen} = useAnalytics()
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
screen('PreferencesExternalEmbeds')
|
||||
setMinimalShellMode(false)
|
||||
}, [screen, setMinimalShellMode]),
|
||||
)
|
||||
|
||||
return (
|
||||
<View style={s.hContentRegion} testID="preferencesExternalEmbedsScreen">
|
||||
<SimpleViewHeader
|
||||
showBackButton={isMobile}
|
||||
style={[
|
||||
pal.border,
|
||||
{borderBottomWidth: 1},
|
||||
!isMobile && {borderLeftWidth: 1, borderRightWidth: 1},
|
||||
]}>
|
||||
<View style={{flex: 1}}>
|
||||
<Text type="title-lg" style={[pal.text, {fontWeight: 'bold'}]}>
|
||||
<Trans>External Media Preferences</Trans>
|
||||
</Text>
|
||||
<Text style={pal.textLight}>
|
||||
<Trans>Customize media from external sites.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</SimpleViewHeader>
|
||||
<ScrollView
|
||||
// @ts-ignore web only -prf
|
||||
dataSet={{'stable-gutters': 1}}
|
||||
contentContainerStyle={[pal.viewLight, {paddingBottom: 200}]}>
|
||||
<View style={[pal.view]}>
|
||||
<View style={styles.infoCard}>
|
||||
<Text style={pal.text}>
|
||||
<Trans>
|
||||
External media may allow websites to collect information about
|
||||
you and your device. No information is sent or requested until
|
||||
you press the "play" button.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||
Enable media players for
|
||||
</Text>
|
||||
{Object.entries(externalEmbedLabels).map(([key, label]) => (
|
||||
<PrefSelector
|
||||
source={key as EmbedPlayerSource}
|
||||
label={label}
|
||||
key={key}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
function PrefSelector({
|
||||
source,
|
||||
label,
|
||||
}: {
|
||||
source: EmbedPlayerSource
|
||||
label: string
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const setExternalEmbedPref = useSetExternalEmbedPref()
|
||||
const sources = useExternalEmbedsPrefs()
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={[pal.view, styles.toggleCard]}>
|
||||
<ToggleButton
|
||||
type="default-light"
|
||||
label={label}
|
||||
labelType="lg"
|
||||
isSelected={sources?.[source] === 'show'}
|
||||
onPress={() =>
|
||||
setExternalEmbedPref(
|
||||
source,
|
||||
sources?.[source] === 'show' ? 'hide' : 'show',
|
||||
)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
heading: {
|
||||
paddingHorizontal: 18,
|
||||
paddingTop: 14,
|
||||
paddingBottom: 14,
|
||||
},
|
||||
spacer: {
|
||||
height: 8,
|
||||
},
|
||||
infoCard: {
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 14,
|
||||
},
|
||||
toggleCard: {
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 6,
|
||||
marginBottom: 1,
|
||||
},
|
||||
})
|
||||
@@ -29,6 +29,7 @@ function RepliesThresholdInput({
|
||||
const pal = usePalette('default')
|
||||
const [value, setValue] = useState(initialValue)
|
||||
const {mutate: setFeedViewPref} = useSetFeedViewPreferencesMutation()
|
||||
const preValue = React.useRef(initialValue)
|
||||
const save = React.useMemo(
|
||||
() =>
|
||||
debounce(
|
||||
@@ -46,7 +47,12 @@ function RepliesThresholdInput({
|
||||
<Slider
|
||||
value={value}
|
||||
onValueChange={(v: number | number[]) => {
|
||||
const threshold = Math.floor(Array.isArray(v) ? v[0] : v)
|
||||
let threshold = Array.isArray(v) ? v[0] : v
|
||||
if (threshold > preValue.current) threshold = Math.floor(threshold)
|
||||
else threshold = Math.ceil(threshold)
|
||||
|
||||
preValue.current = threshold
|
||||
|
||||
setValue(threshold)
|
||||
save(threshold)
|
||||
}}
|
||||
|
||||
@@ -82,7 +82,7 @@ export function SavedFeeds({}: Props) {
|
||||
isTabletOrDesktop && styles.desktopContainer,
|
||||
]}>
|
||||
<ViewHeader title={_(msg`Edit My Feeds`)} showOnDesktop showBorder />
|
||||
<ScrollView style={s.flex1}>
|
||||
<ScrollView style={s.flex1} contentContainerStyle={[styles.noBorder]}>
|
||||
<View style={[pal.text, pal.border, styles.title]}>
|
||||
<Text type="title" style={pal.text}>
|
||||
<Trans>Pinned Feeds</Trans>
|
||||
@@ -288,7 +288,7 @@ function ListItem({
|
||||
<FeedSourceCard
|
||||
key={feedUri}
|
||||
feedUri={feedUri}
|
||||
style={styles.noBorder}
|
||||
style={styles.noTopBorder}
|
||||
showSaveBtn
|
||||
showMinimalPlaceholder
|
||||
/>
|
||||
@@ -344,7 +344,7 @@ const styles = StyleSheet.create({
|
||||
webArrowUpButton: {
|
||||
marginBottom: 10,
|
||||
},
|
||||
noBorder: {
|
||||
noTopBorder: {
|
||||
borderTopWidth: 0,
|
||||
},
|
||||
footerText: {
|
||||
@@ -352,4 +352,10 @@ const styles = StyleSheet.create({
|
||||
paddingTop: 22,
|
||||
paddingBottom: 100,
|
||||
},
|
||||
noBorder: {
|
||||
borderBottomWidth: 0,
|
||||
borderRightWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderTopWidth: 0,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -419,7 +419,7 @@ export function SettingsScreen({}: Props) {
|
||||
<View style={[pal.view, styles.toggleCard]}>
|
||||
<ToggleButton
|
||||
type="default-light"
|
||||
label="Require alt text before posting"
|
||||
label={_(msg`Require alt text before posting`)}
|
||||
labelType="lg"
|
||||
isSelected={requireAltTextEnabled}
|
||||
onPress={() => setRequireAltTextEnabled(!requireAltTextEnabled)}
|
||||
@@ -563,6 +563,39 @@ export function SettingsScreen({}: Props) {
|
||||
<Trans>Moderation</Trans>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.spacer20} />
|
||||
|
||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||
<Trans>Privacy</Trans>
|
||||
</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
testID="externalEmbedsBtn"
|
||||
style={[
|
||||
styles.linkCard,
|
||||
pal.view,
|
||||
isSwitchingAccounts && styles.dimmed,
|
||||
]}
|
||||
onPress={
|
||||
isSwitchingAccounts
|
||||
? undefined
|
||||
: () => navigation.navigate('PreferencesExternalEmbeds')
|
||||
}
|
||||
accessibilityRole="button"
|
||||
accessibilityHint=""
|
||||
accessibilityLabel={_(msg`Opens external embeds settings`)}>
|
||||
<View style={[styles.iconContainer, pal.btn]}>
|
||||
<FontAwesomeIcon
|
||||
icon={['far', 'circle-play']}
|
||||
style={pal.text as FontAwesomeIconStyle}
|
||||
/>
|
||||
</View>
|
||||
<Text type="lg" style={pal.text}>
|
||||
<Trans>External Media Preferences</Trans>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.spacer20} />
|
||||
|
||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||
|
||||
@@ -5,6 +5,10 @@ import {ComposePost} from '../com/composer/Composer'
|
||||
import {useComposerState} from 'state/shell/composer'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {
|
||||
EmojiPicker,
|
||||
EmojiPickerState,
|
||||
} from 'view/com/composer/text-input/web/EmojiPicker.web.tsx'
|
||||
|
||||
const BOTTOM_BAR_HEIGHT = 61
|
||||
|
||||
@@ -13,6 +17,26 @@ export function Composer({}: {winHeight: number}) {
|
||||
const {isMobile} = useWebMediaQueries()
|
||||
const state = useComposerState()
|
||||
|
||||
const [pickerState, setPickerState] = React.useState<EmojiPickerState>({
|
||||
isOpen: false,
|
||||
pos: {top: 0, left: 0, right: 0, bottom: 0},
|
||||
})
|
||||
|
||||
const onOpenPicker = React.useCallback((pos: DOMRect | undefined) => {
|
||||
if (!pos) return
|
||||
setPickerState({
|
||||
isOpen: true,
|
||||
pos,
|
||||
})
|
||||
}, [])
|
||||
|
||||
const onClosePicker = React.useCallback(() => {
|
||||
setPickerState(prev => ({
|
||||
...prev,
|
||||
isOpen: false,
|
||||
}))
|
||||
}, [])
|
||||
|
||||
// rendering
|
||||
// =
|
||||
|
||||
@@ -41,8 +65,10 @@ export function Composer({}: {winHeight: number}) {
|
||||
quote={state.quote}
|
||||
onPost={state.onPost}
|
||||
mention={state.mention}
|
||||
openPicker={onOpenPicker}
|
||||
/>
|
||||
</Animated.View>
|
||||
<EmojiPicker state={pickerState} close={onClosePicker} />
|
||||
</Animated.View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -180,14 +180,14 @@ const styles = StyleSheet.create({
|
||||
position: 'absolute',
|
||||
// @ts-ignore web only
|
||||
left: 'calc(50vw + 320px)',
|
||||
width: 304,
|
||||
width: 300,
|
||||
maxHeight: '100%',
|
||||
overflowY: 'auto',
|
||||
},
|
||||
|
||||
message: {
|
||||
paddingVertical: 18,
|
||||
paddingHorizontal: 10,
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
messageLine: {
|
||||
marginBottom: 10,
|
||||
@@ -195,7 +195,7 @@ const styles = StyleSheet.create({
|
||||
|
||||
inviteCodes: {
|
||||
borderTopWidth: 1,
|
||||
paddingHorizontal: 16,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"types": ["react-native", "jest"],
|
||||
"lib": [
|
||||
"es2019",
|
||||
"es2020.bigint",
|
||||
"es2020.date",
|
||||
"es2020.number",
|
||||
"es2020.promise",
|
||||
"es2020.string",
|
||||
"es2020.symbol.wellknown",
|
||||
"es2021.promise",
|
||||
"es2021.string",
|
||||
"es2021.weakref",
|
||||
"es2022.array",
|
||||
"es2022.object",
|
||||
"es2022.string"
|
||||
],
|
||||
"allowJs": true,
|
||||
"jsx": "react-native",
|
||||
"noEmit": true,
|
||||
"isolatedModules": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"#/*": ["./src/*"],
|
||||
"lib/*": ["./src/lib/*"],
|
||||
"platform/*": ["./src/platform/*"],
|
||||
"state/*": ["./src/state/*"],
|
||||
"view/*": ["./src/view/*"],
|
||||
"crypto": ["./src/platform/crypto.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"babel.config.js",
|
||||
"metro.config.js",
|
||||
"jest.config.js"
|
||||
]
|
||||
}
|
||||
@@ -3335,6 +3335,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@fastify/deepmerge/-/deepmerge-1.3.0.tgz#8116858108f0c7d9fd460d05a7d637a13fe3239a"
|
||||
integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==
|
||||
|
||||
"@flatten-js/interval-tree@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@flatten-js/interval-tree/-/interval-tree-1.1.2.tgz#fcc891da48bc230392884be01c26fe8c625702e8"
|
||||
integrity sha512-OwLoV9E/XM6b7bes2rSFnGNjyRy7vcoIHFTnmBR2WAaZTf0Fe4EX4GdA65vU1KgFAasti7iRSg2dZfYd1Zt00Q==
|
||||
|
||||
"@floating-ui/core@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.4.1.tgz#0d633f4b76052668afb932492ac452f7ebe97f17"
|
||||
@@ -8986,6 +8991,16 @@ builtins@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
|
||||
integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==
|
||||
|
||||
bunyamin@^1.5.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/bunyamin/-/bunyamin-1.5.1.tgz#14df1b2f0b82d781d8f8d81eb2e83542353ac8d7"
|
||||
integrity sha512-VgWWb3G3HwajZF8fFM8TJjkWOqeDBZgzWBeQb7EhKQTQd33Zri0nghLeg4r86kQqqNlo/p9Jjgwh/O7Q6XpZIg==
|
||||
dependencies:
|
||||
"@flatten-js/interval-tree" "^1.1.2"
|
||||
multi-sort-stream "^1.0.4"
|
||||
stream-json "^1.7.5"
|
||||
trace-event-lib "^1.3.1"
|
||||
|
||||
bunyan-debug-stream@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-3.1.0.tgz#78309c67ad85cfb8f011155334152c49209dcda8"
|
||||
@@ -9003,6 +9018,18 @@ bunyan@^1.8.12:
|
||||
mv "~2"
|
||||
safe-json-stringify "~1"
|
||||
|
||||
bunyan@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-2.0.5.tgz#9dd056755220dddd8b5bb9cf76f3d0d766e96e71"
|
||||
integrity sha512-Jvl74TdxCN6rSP9W1I6+UOUtwslTDqsSFkDqZlFb/ilaSvQ+bZAnXT/GT97IZ5L+Vph0joPZPhxUyn6FLNmFAA==
|
||||
dependencies:
|
||||
exeunt "1.1.0"
|
||||
optionalDependencies:
|
||||
dtrace-provider "~0.8"
|
||||
moment "^2.19.3"
|
||||
mv "~2"
|
||||
safe-json-stringify "~1"
|
||||
|
||||
bytes@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||
@@ -10304,10 +10331,10 @@ detect-port-alt@^1.1.6:
|
||||
address "^1.0.1"
|
||||
debug "^2.6.0"
|
||||
|
||||
detox@^20.13.0:
|
||||
version "20.13.0"
|
||||
resolved "https://registry.yarnpkg.com/detox/-/detox-20.13.0.tgz#923111638dfdb16089eea4f07bf4f0b56468d097"
|
||||
integrity sha512-p9MUcoHWFTqSDaoaN+/hnJYdzNYqdelUr/sxzy3zLoS/qehnVJv2yG9pYqz/+gKpJaMIpw2+TVw9imdAx5JpaA==
|
||||
detox@^20.14.8:
|
||||
version "20.14.8"
|
||||
resolved "https://registry.yarnpkg.com/detox/-/detox-20.14.8.tgz#0a550cf677fc98a68d56d162e1c5caad317de9ca"
|
||||
integrity sha512-3E/0/7Cb7x+wcBsZpCxD8FykZUsFnfVT00d6PWH940boc0Mo1Kzabh+I151X/On4qZMqVdUzgwmap/z8g/kmaw==
|
||||
dependencies:
|
||||
ajv "^8.6.3"
|
||||
bunyan "^1.8.12"
|
||||
@@ -10321,6 +10348,7 @@ detox@^20.13.0:
|
||||
funpermaproxy "^1.1.0"
|
||||
glob "^8.0.3"
|
||||
ini "^1.3.4"
|
||||
jest-environment-emit "^1.0.5"
|
||||
json-cycle "^1.3.0"
|
||||
lodash "^4.17.11"
|
||||
multi-sort-stream "^1.0.3"
|
||||
@@ -11339,6 +11367,11 @@ execa@^5.0.0, execa@^5.1.1:
|
||||
signal-exit "^3.0.3"
|
||||
strip-final-newline "^2.0.0"
|
||||
|
||||
exeunt@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/exeunt/-/exeunt-1.1.0.tgz#af72db6f94b3cb75e921aee375d513049843d284"
|
||||
integrity sha512-dd++Yn/0Fp+gtJ04YHov7MeAii+LFivJc6KqnJNfplzLVUkUDrfKoQDTLlCgzcW15vY5hKlHasWeIsQJ8agHsw==
|
||||
|
||||
exit@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||
@@ -13772,6 +13805,20 @@ jest-each@^29.7.0:
|
||||
jest-util "^29.7.0"
|
||||
pretty-format "^29.7.0"
|
||||
|
||||
jest-environment-emit@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.5.tgz#e6f33451f98b88ccd48e9e1188bb535880f03c1b"
|
||||
integrity sha512-OsQ08AhYxkkyDBTIow+9ogNmJheQIGWQKp0Nku+1ToLWjAj2Pd6LmypN8HgUIqYHs4HFcqkQ25kaf1qExmoZpg==
|
||||
dependencies:
|
||||
bunyamin "^1.5.0"
|
||||
bunyan "^2.0.5"
|
||||
bunyan-debug-stream "^3.1.0"
|
||||
funpermaproxy "^1.1.0"
|
||||
lodash.merge "^4.6.2"
|
||||
node-ipc "9.2.1"
|
||||
strip-ansi "^6.0.0"
|
||||
tslib "^2.5.3"
|
||||
|
||||
jest-environment-jsdom@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546"
|
||||
@@ -15868,7 +15915,7 @@ ms@2.1.3, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
multi-sort-stream@^1.0.3:
|
||||
multi-sort-stream@^1.0.3, multi-sort-stream@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/multi-sort-stream/-/multi-sort-stream-1.0.4.tgz#e4348edc9edc36e16333e531a90c0f166235cc99"
|
||||
integrity sha512-hAZ8JOEQFbgdLe8HWZbb7gdZg0/yAIHF00Qfo3kd0rXFv96nXe+/bPTrKHZ2QMHugGX4FiAyET1Lt+jiB+7Qlg==
|
||||
@@ -18198,11 +18245,6 @@ react-native-screens@~3.27.0:
|
||||
react-freeze "^1.0.0"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
react-native-splash-screen@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.3.0.tgz#3af71ed17afe50fee69590a45aec399d071ead02"
|
||||
integrity sha512-rGjt6HkoSXxMqH4SQUJ1gnPQlPJV8+J47+4yhgTIan4bVvAwJhEeJH7wWt9hXSdH4+VfwTS0GTaflj1Tw83IhA==
|
||||
|
||||
react-native-svg@14.0.0:
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-14.0.0.tgz#ea1974dec9a91a09c6a38b7bf58d85e857c291f5"
|
||||
@@ -18262,13 +18304,6 @@ react-native-webview@^13.6.3:
|
||||
escape-string-regexp "2.0.0"
|
||||
invariant "2.2.4"
|
||||
|
||||
react-native-youtube-iframe@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-youtube-iframe/-/react-native-youtube-iframe-2.3.0.tgz#40ca8e55db929b91bfa8e8d30e411658cbc304c5"
|
||||
integrity sha512-M+z63xwXVtS4dX3k8PbtHUUcWN+gRZt6J1EtPE7Y60BMOB979KjpkdrHqeR96or9pNR2W8K5tQhIkMXW2jwo7Q==
|
||||
dependencies:
|
||||
events "^3.2.0"
|
||||
|
||||
react-native@0.73.1:
|
||||
version "0.73.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.73.1.tgz#5eafaa7e54feeab8b55e8b8e4efc4d21052a4fff"
|
||||
@@ -19624,7 +19659,7 @@ stream-chain@^2.2.5:
|
||||
resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09"
|
||||
integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==
|
||||
|
||||
stream-json@^1.7.4:
|
||||
stream-json@^1.7.4, stream-json@^1.7.5:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.8.0.tgz#53f486b2e3b4496c506131f8d7260ba42def151c"
|
||||
integrity sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==
|
||||
@@ -20398,7 +20433,7 @@ tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0:
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0, tslib@^2.5.3:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
Reference in New Issue
Block a user