Merge remote-tracking branch 'upstream/main' into Improve-notification-localization
This commit is contained in:
@@ -372,7 +372,7 @@ function VideoEmbed({content}: {content: AppBskyEmbedVideo.View}) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full overflow-hidden rounded-lg aspect-square"
|
||||
className="w-full overflow-hidden rounded-lg aspect-square relative"
|
||||
style={{aspectRatio: `${aspectRatio} / 1`}}>
|
||||
<img
|
||||
src={content.thumbnail}
|
||||
|
||||
@@ -259,7 +259,6 @@
|
||||
pointer-events: none !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
{% include "scripts.html" %}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@
|
||||
"open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@atproto/api": "0.13.5",
|
||||
"@atproto/api": "^0.13.7",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
||||
"@braintree/sanitize-url": "^6.0.2",
|
||||
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
|
||||
const MessageContext = React.createContext(false)
|
||||
|
||||
export function MessageContextProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<MessageContext.Provider value={true}>{children}</MessageContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useIsWithinMessage() {
|
||||
return React.useContext(MessageContext)
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import {AppBskyEmbedRecord} from '@atproto/api'
|
||||
|
||||
import {PostEmbeds, PostEmbedViewContext} from '#/view/com/util/post-embeds'
|
||||
import {atoms as a, native, useTheme} from '#/alf'
|
||||
import {MessageContextProvider} from './MessageContext'
|
||||
|
||||
let MessageItemEmbed = ({
|
||||
embed,
|
||||
@@ -13,6 +14,7 @@ let MessageItemEmbed = ({
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<MessageContextProvider>
|
||||
<View style={[a.my_xs, t.atoms.bg, native({flexBasis: 0})]}>
|
||||
<PostEmbeds
|
||||
embed={embed}
|
||||
@@ -20,6 +22,7 @@ let MessageItemEmbed = ({
|
||||
viewContext={PostEmbedViewContext.Feed}
|
||||
/>
|
||||
</View>
|
||||
</MessageContextProvider>
|
||||
)
|
||||
}
|
||||
MessageItemEmbed = React.memo(MessageItemEmbed)
|
||||
|
||||
@@ -5,7 +5,7 @@ import {SUPPORTED_MIME_TYPES, SupportedMimeTypes} from '#/lib/constants'
|
||||
import {extToMime} from '#/state/queries/video/util'
|
||||
import {CompressedVideo} from './types'
|
||||
|
||||
const MIN_SIZE_FOR_COMPRESSION = 1024 * 1024 * 25 // 25mb
|
||||
const MIN_SIZE_FOR_COMPRESSION = 25 // 25mb
|
||||
|
||||
export async function compressVideo(
|
||||
file: ImagePickerAsset,
|
||||
@@ -30,6 +30,7 @@ export async function compressVideo(
|
||||
compressionMethod: 'manual',
|
||||
bitrate: 3_000_000, // 3mbps
|
||||
maxSize: 1920,
|
||||
// WARNING: this ONE SPECIFIC ARG is in MB -sfn
|
||||
minimumFileSizeForCompress,
|
||||
getCancellationId: id => {
|
||||
if (signal) {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
export type Gate =
|
||||
// Keep this alphabetic please.
|
||||
| 'debug_show_feedcontext'
|
||||
| 'suggested_feeds_interstitial'
|
||||
| 'video_upload' // upload videos
|
||||
| 'video_view_on_posts' // see posted videos
|
||||
'debug_show_feedcontext' | 'suggested_feeds_interstitial' | 'video_upload' // upload videos
|
||||
|
||||
@@ -127,7 +127,7 @@ msgstr ""
|
||||
msgid "{0} joined this week"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:593
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:637
|
||||
msgid "{0} of {1}"
|
||||
msgstr ""
|
||||
|
||||
@@ -461,7 +461,7 @@ msgstr ""
|
||||
#~ msgid "Add ALT text"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:107
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:109
|
||||
msgid "Add alt text (optional)"
|
||||
msgstr ""
|
||||
|
||||
@@ -607,9 +607,9 @@ msgid "ALT"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/GifAltText.tsx:144
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:54
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:102
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:106
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:56
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:104
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:108
|
||||
#: src/view/com/modals/EditImage.tsx:316
|
||||
#: src/view/screens/AccessibilitySettings.tsx:87
|
||||
msgid "Alt text"
|
||||
@@ -640,7 +640,7 @@ msgstr ""
|
||||
#~ msgid "An error occured"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:369
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:413
|
||||
msgid "An error occurred"
|
||||
msgstr ""
|
||||
|
||||
@@ -652,11 +652,11 @@ msgstr ""
|
||||
msgid "An error occurred while generating your starter pack. Want to try again?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:213
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:215
|
||||
msgid "An error occurred while loading the video. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:170
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:171
|
||||
msgid "An error occurred while loading the video. Please try again."
|
||||
msgstr ""
|
||||
|
||||
@@ -669,7 +669,7 @@ msgstr ""
|
||||
msgid "An error occurred while saving the QR code!"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:61
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:68
|
||||
msgid "An error occurred while selecting the video"
|
||||
msgstr ""
|
||||
|
||||
@@ -844,7 +844,7 @@ msgstr ""
|
||||
msgid "Are you sure you want to remove this from your feeds?"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:837
|
||||
#: src/view/com/composer/Composer.tsx:841
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr ""
|
||||
|
||||
@@ -1096,8 +1096,8 @@ msgstr ""
|
||||
#: src/components/Prompt.tsx:124
|
||||
#: src/components/TagMenu/index.tsx:282
|
||||
#: src/screens/Deactivated.tsx:161
|
||||
#: src/view/com/composer/Composer.tsx:591
|
||||
#: src/view/com/composer/Composer.tsx:606
|
||||
#: src/view/com/composer/Composer.tsx:595
|
||||
#: src/view/com/composer/Composer.tsx:610
|
||||
#: src/view/com/modals/ChangeEmail.tsx:213
|
||||
#: src/view/com/modals/ChangeEmail.tsx:215
|
||||
#: src/view/com/modals/ChangeHandle.tsx:148
|
||||
@@ -1165,11 +1165,11 @@ msgstr ""
|
||||
msgid "Cannot interact with a blocked user"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:133
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:135
|
||||
msgid "Captions (.vtt)"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:54
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:56
|
||||
msgid "Captions & alt text"
|
||||
msgstr ""
|
||||
|
||||
@@ -1457,7 +1457,7 @@ msgstr ""
|
||||
msgid "Closes password update alert"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:603
|
||||
#: src/view/com/composer/Composer.tsx:607
|
||||
msgid "Closes post composer and discards post draft"
|
||||
msgstr ""
|
||||
|
||||
@@ -1496,7 +1496,7 @@ msgstr ""
|
||||
msgid "Complete the challenge"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:711
|
||||
#: src/view/com/composer/Composer.tsx:715
|
||||
msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length"
|
||||
msgstr ""
|
||||
|
||||
@@ -1742,7 +1742,7 @@ msgstr ""
|
||||
msgid "Could not mute chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:45
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:56
|
||||
msgid "Could not process your video"
|
||||
msgstr ""
|
||||
|
||||
@@ -2005,7 +2005,7 @@ msgstr ""
|
||||
msgid "Dialog: adjust who can interact with this post"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:352
|
||||
#: src/view/com/composer/Composer.tsx:356
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr ""
|
||||
|
||||
@@ -2038,7 +2038,7 @@ msgstr ""
|
||||
#~ msgid "Disable haptics"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:335
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:379
|
||||
msgid "Disable subtitles"
|
||||
msgstr ""
|
||||
|
||||
@@ -2055,11 +2055,11 @@ msgstr ""
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:839
|
||||
#: src/view/com/composer/Composer.tsx:843
|
||||
msgid "Discard"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:836
|
||||
#: src/view/com/composer/Composer.tsx:840
|
||||
msgid "Discard draft?"
|
||||
msgstr ""
|
||||
|
||||
@@ -2089,7 +2089,7 @@ msgstr ""
|
||||
#~ msgid "Dismiss"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:1106
|
||||
#: src/view/com/composer/Composer.tsx:1110
|
||||
msgid "Dismiss error"
|
||||
msgstr ""
|
||||
|
||||
@@ -2141,8 +2141,8 @@ msgstr ""
|
||||
#: src/screens/Onboarding/StepProfile/index.tsx:325
|
||||
#: src/view/com/auth/server-input/index.tsx:169
|
||||
#: src/view/com/auth/server-input/index.tsx:170
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:167
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:177
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:171
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:181
|
||||
#: src/view/com/modals/AddAppPasswords.tsx:243
|
||||
#: src/view/com/modals/AltImage.tsx:141
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:177
|
||||
@@ -2417,7 +2417,7 @@ msgstr ""
|
||||
msgid "Enable priority notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:336
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:380
|
||||
msgid "Enable subtitles"
|
||||
msgstr ""
|
||||
|
||||
@@ -2447,7 +2447,7 @@ msgstr ""
|
||||
#~ msgid "End of onboarding tour window. Do not move forward. Instead, go backward for more options, or press to skip."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:157
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:161
|
||||
msgid "Ensure you have selected a language for each subtitle file."
|
||||
msgstr ""
|
||||
|
||||
@@ -2549,7 +2549,7 @@ msgstr ""
|
||||
msgid "Excludes users you follow"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:353
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:397
|
||||
msgid "Exit fullscreen"
|
||||
msgstr ""
|
||||
|
||||
@@ -3057,7 +3057,7 @@ msgctxt "from-feed"
|
||||
msgid "From <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:354
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:398
|
||||
msgid "Fullscreen"
|
||||
msgstr ""
|
||||
|
||||
@@ -3526,7 +3526,7 @@ msgstr ""
|
||||
msgid "It's just you right now! Add more people to your starter pack by searching above."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:1125
|
||||
#: src/view/com/composer/Composer.tsx:1129
|
||||
msgid "Job ID: {0}"
|
||||
msgstr ""
|
||||
|
||||
@@ -4046,12 +4046,12 @@ msgstr ""
|
||||
msgid "Music"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:345
|
||||
msgctxt "video"
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:389
|
||||
msgctxt "video"
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
|
||||
@@ -4583,7 +4583,7 @@ msgstr ""
|
||||
#~ msgid "Onboarding tour step {0}: {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:668
|
||||
#: src/view/com/composer/Composer.tsx:672
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr ""
|
||||
|
||||
@@ -4638,8 +4638,8 @@ msgid "Open conversation options"
|
||||
msgstr ""
|
||||
|
||||
#: src/screens/Messages/Conversation/MessageInput.web.tsx:165
|
||||
#: src/view/com/composer/Composer.tsx:819
|
||||
#: src/view/com/composer/Composer.tsx:820
|
||||
#: src/view/com/composer/Composer.tsx:823
|
||||
#: src/view/com/composer/Composer.tsx:824
|
||||
msgid "Open emoji picker"
|
||||
msgstr ""
|
||||
|
||||
@@ -4825,7 +4825,7 @@ msgstr ""
|
||||
msgid "Opens this profile"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:81
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:88
|
||||
msgid "Opens video picker"
|
||||
msgstr ""
|
||||
|
||||
@@ -4903,11 +4903,11 @@ msgid "Password updated!"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/GifEmbed.tsx:44
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:322
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:366
|
||||
msgid "Pause"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:275
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:319
|
||||
msgid "Pause video"
|
||||
msgstr ""
|
||||
|
||||
@@ -4967,7 +4967,7 @@ msgid "Pinned to your feeds"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/GifEmbed.tsx:44
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:323
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:367
|
||||
msgid "Play"
|
||||
msgstr ""
|
||||
|
||||
@@ -4984,8 +4984,8 @@ msgstr ""
|
||||
msgid "Play or pause the GIF"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:187
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:276
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:189
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:320
|
||||
msgid "Play video"
|
||||
msgstr ""
|
||||
|
||||
@@ -5057,7 +5057,7 @@ msgstr ""
|
||||
msgid "Please Verify Your Email"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:356
|
||||
#: src/view/com/composer/Composer.tsx:360
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr ""
|
||||
|
||||
@@ -5070,8 +5070,8 @@ msgstr ""
|
||||
msgid "Porn"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:643
|
||||
#: src/view/com/composer/Composer.tsx:650
|
||||
#: src/view/com/composer/Composer.tsx:647
|
||||
#: src/view/com/composer/Composer.tsx:654
|
||||
msgctxt "action"
|
||||
msgid "Post"
|
||||
msgstr ""
|
||||
@@ -5250,11 +5250,11 @@ msgstr ""
|
||||
msgid "Public, shareable lists which can drive feeds."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:628
|
||||
#: src/view/com/composer/Composer.tsx:632
|
||||
msgid "Publish post"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:628
|
||||
#: src/view/com/composer/Composer.tsx:632
|
||||
msgid "Publish reply"
|
||||
msgstr ""
|
||||
|
||||
@@ -5482,7 +5482,7 @@ msgstr ""
|
||||
msgid "Remove repost"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:260
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:264
|
||||
msgid "Remove subtitle file"
|
||||
msgstr ""
|
||||
|
||||
@@ -5559,7 +5559,7 @@ msgstr ""
|
||||
#~ msgid "Replies to this thread are disabled"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:641
|
||||
#: src/view/com/composer/Composer.tsx:645
|
||||
msgctxt "action"
|
||||
msgid "Reply"
|
||||
msgstr ""
|
||||
@@ -6053,7 +6053,7 @@ msgstr ""
|
||||
#~ msgid "See what's next"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:587
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:631
|
||||
msgid "Seek slider"
|
||||
msgstr ""
|
||||
|
||||
@@ -6093,7 +6093,7 @@ msgstr ""
|
||||
msgid "Select how long to mute this word for."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:245
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:249
|
||||
msgid "Select language..."
|
||||
msgstr ""
|
||||
|
||||
@@ -6133,7 +6133,7 @@ msgstr ""
|
||||
#~ msgid "Select topical feeds to follow from the list below"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:80
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:87
|
||||
msgid "Select video"
|
||||
msgstr ""
|
||||
|
||||
@@ -7429,7 +7429,7 @@ msgstr ""
|
||||
msgid "To report a conversation, please report one of its messages via the conversation screen. This lets our moderators understand the context of your issue."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:106
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:113
|
||||
msgid "To upload videos to Bluesky, you must first verify your email."
|
||||
msgstr ""
|
||||
|
||||
@@ -7572,13 +7572,13 @@ msgstr ""
|
||||
msgid "Unlike this feed"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:344
|
||||
msgctxt "video"
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
#: src/view/screens/ProfileList.tsx:689
|
||||
msgid "Unmute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
#: src/view/screens/ProfileList.tsx:689
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:388
|
||||
msgctxt "video"
|
||||
msgid "Unmute"
|
||||
msgstr ""
|
||||
|
||||
@@ -7608,7 +7608,7 @@ msgstr ""
|
||||
msgid "Unmute thread"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:273
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:317
|
||||
msgid "Unmute video"
|
||||
msgstr ""
|
||||
|
||||
@@ -7837,7 +7837,7 @@ msgstr ""
|
||||
msgid "Value:"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:104
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:111
|
||||
msgid "Verified email required"
|
||||
msgstr ""
|
||||
|
||||
@@ -7870,7 +7870,7 @@ msgstr ""
|
||||
msgid "Verify New Email"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:108
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:115
|
||||
msgid "Verify now"
|
||||
msgstr ""
|
||||
|
||||
@@ -7904,11 +7904,11 @@ msgstr ""
|
||||
msgid "Video Games"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:163
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:164
|
||||
msgid "Video not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:99
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:101
|
||||
msgid "Video settings"
|
||||
msgstr ""
|
||||
|
||||
@@ -7920,6 +7920,11 @@ msgstr ""
|
||||
#~ msgid "Videos cannot be larger than 50MB"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:58
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:44
|
||||
msgid "Videos must be less than 60 seconds long"
|
||||
msgstr ""
|
||||
|
||||
#: src/screens/Profile/Header/Shell.tsx:113
|
||||
msgid "View {0}'s avatar"
|
||||
msgstr ""
|
||||
@@ -8093,7 +8098,7 @@ msgstr ""
|
||||
msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
#: src/view/com/composer/Composer.tsx:422
|
||||
msgid "We're sorry! The post you are replying to has been deleted."
|
||||
msgstr ""
|
||||
|
||||
@@ -8132,7 +8137,7 @@ msgstr ""
|
||||
|
||||
#: src/view/com/auth/SplashScreen.tsx:40
|
||||
#: src/view/com/auth/SplashScreen.web.tsx:86
|
||||
#: src/view/com/composer/Composer.tsx:513
|
||||
#: src/view/com/composer/Composer.tsx:517
|
||||
msgid "What's up?"
|
||||
msgstr ""
|
||||
|
||||
@@ -8207,11 +8212,11 @@ msgstr ""
|
||||
msgid "Write a message"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:709
|
||||
#: src/view/com/composer/Composer.tsx:713
|
||||
msgid "Write post"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:512
|
||||
#: src/view/com/composer/Composer.tsx:516
|
||||
#: src/view/com/post-thread/PostThreadComposePrompt.tsx:42
|
||||
msgid "Write your reply"
|
||||
msgstr ""
|
||||
@@ -8571,7 +8576,7 @@ msgstr ""
|
||||
msgid "Your birth date"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:167
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:168
|
||||
msgid "Your browser does not support the video format. Please try a different browser."
|
||||
msgstr ""
|
||||
|
||||
@@ -8626,7 +8631,7 @@ msgstr ""
|
||||
msgid "Your password has been changed successfully!"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:464
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
msgid "Your post has been published"
|
||||
msgstr ""
|
||||
|
||||
@@ -8642,7 +8647,7 @@ msgstr ""
|
||||
msgid "Your profile, posts, feeds, and lists will no longer be visible to other Bluesky users. You can reactivate your account at any time by logging in."
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:463
|
||||
#: src/view/com/composer/Composer.tsx:467
|
||||
msgid "Your reply has been published"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ msgstr ""
|
||||
msgid "{0} joined this week"
|
||||
msgstr "{0} entrou esta semana"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:593
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:637
|
||||
msgid "{0} of {1}"
|
||||
msgstr ""
|
||||
|
||||
@@ -461,7 +461,7 @@ msgstr "Adicionar texto alternativo"
|
||||
#~ msgid "Add ALT text"
|
||||
#~ msgstr "Adicionar texto alternativo"
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:107
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:109
|
||||
msgid "Add alt text (optional)"
|
||||
msgstr "Adicionar texto alternativo (opcional)"
|
||||
|
||||
@@ -607,9 +607,9 @@ msgid "ALT"
|
||||
msgstr "ALT"
|
||||
|
||||
#: src/view/com/composer/GifAltText.tsx:144
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:54
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:102
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:106
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:56
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:104
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:108
|
||||
#: src/view/com/modals/EditImage.tsx:316
|
||||
#: src/view/screens/AccessibilitySettings.tsx:87
|
||||
msgid "Alt text"
|
||||
@@ -640,7 +640,7 @@ msgstr "Ocorreu um erro"
|
||||
#~ msgid "An error occured"
|
||||
#~ msgstr "Tivemos um problema"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:369
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:413
|
||||
msgid "An error occurred"
|
||||
msgstr "Ocorreu um erro"
|
||||
|
||||
@@ -652,11 +652,11 @@ msgstr "Ocorreu um erro ao compactar o vídeo."
|
||||
msgid "An error occurred while generating your starter pack. Want to try again?"
|
||||
msgstr "Ocorreu um erro ao gerar seu pacote inicial. Quer tentar novamente?"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:213
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:215
|
||||
msgid "An error occurred while loading the video. Please try again later."
|
||||
msgstr "Ocorreu um erro ao carregar o vídeo. Tente novamente mais tarde."
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:170
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:171
|
||||
msgid "An error occurred while loading the video. Please try again."
|
||||
msgstr "Ocorreu um erro ao carregar o vídeo. Tente novamente."
|
||||
|
||||
@@ -669,7 +669,7 @@ msgstr "Ocorreu um erro ao carregar o vídeo. Tente novamente."
|
||||
msgid "An error occurred while saving the QR code!"
|
||||
msgstr "Ocorreu um erro ao salvar o QR code!"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:61
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:68
|
||||
msgid "An error occurred while selecting the video"
|
||||
msgstr "Ocorreu um erro ao selecionar o vídeo"
|
||||
|
||||
@@ -844,7 +844,7 @@ msgstr "Tem certeza que deseja remover {0} dos seus feeds?"
|
||||
msgid "Are you sure you want to remove this from your feeds?"
|
||||
msgstr "Tem certeza que deseja remover isto de seus feeds?"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:837
|
||||
#: src/view/com/composer/Composer.tsx:841
|
||||
msgid "Are you sure you'd like to discard this draft?"
|
||||
msgstr "Tem certeza que deseja descartar este rascunho?"
|
||||
|
||||
@@ -1096,8 +1096,8 @@ msgstr "Só pode conter letras, números, espaços, riscas e subtraços. Deve te
|
||||
#: src/components/Prompt.tsx:124
|
||||
#: src/components/TagMenu/index.tsx:282
|
||||
#: src/screens/Deactivated.tsx:161
|
||||
#: src/view/com/composer/Composer.tsx:591
|
||||
#: src/view/com/composer/Composer.tsx:606
|
||||
#: src/view/com/composer/Composer.tsx:595
|
||||
#: src/view/com/composer/Composer.tsx:610
|
||||
#: src/view/com/modals/ChangeEmail.tsx:213
|
||||
#: src/view/com/modals/ChangeEmail.tsx:215
|
||||
#: src/view/com/modals/ChangeHandle.tsx:148
|
||||
@@ -1165,11 +1165,11 @@ msgstr "Cancela a abertura do link"
|
||||
msgid "Cannot interact with a blocked user"
|
||||
msgstr ""
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:133
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:135
|
||||
msgid "Captions (.vtt)"
|
||||
msgstr "Legendas (.vtt)"
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:54
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:56
|
||||
msgid "Captions & alt text"
|
||||
msgstr "Legendas e texto alt"
|
||||
|
||||
@@ -1457,7 +1457,7 @@ msgstr "Fecha barra de navegação inferior"
|
||||
msgid "Closes password update alert"
|
||||
msgstr "Fecha alerta de troca de senha"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:603
|
||||
#: src/view/com/composer/Composer.tsx:607
|
||||
msgid "Closes post composer and discards post draft"
|
||||
msgstr "Fecha o editor de post e descarta o rascunho"
|
||||
|
||||
@@ -1496,7 +1496,7 @@ msgstr "Completar e começar a usar sua conta"
|
||||
msgid "Complete the challenge"
|
||||
msgstr "Complete o captcha"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:711
|
||||
#: src/view/com/composer/Composer.tsx:715
|
||||
msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length"
|
||||
msgstr "Escreva posts de até {MAX_GRAPHEME_LENGTH} caracteres"
|
||||
|
||||
@@ -1742,7 +1742,7 @@ msgstr "Não foi possível carregar a lista"
|
||||
msgid "Could not mute chat"
|
||||
msgstr "Não foi possível silenciar este chat"
|
||||
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:45
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:56
|
||||
msgid "Could not process your video"
|
||||
msgstr "Não foi possível processar seu vídeo"
|
||||
|
||||
@@ -2005,7 +2005,7 @@ msgstr "Desanexar postagem de citação?"
|
||||
msgid "Dialog: adjust who can interact with this post"
|
||||
msgstr "Diálogo: ajuste quem pode interagir com esta postagem"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:352
|
||||
#: src/view/com/composer/Composer.tsx:356
|
||||
msgid "Did you want to say anything?"
|
||||
msgstr "Você gostaria de dizer alguma coisa?"
|
||||
|
||||
@@ -2038,7 +2038,7 @@ msgstr "Desabilitar feedback tátil"
|
||||
#~ msgid "Disable haptics"
|
||||
#~ msgstr "Desabilitar feedback tátil"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:335
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:379
|
||||
msgid "Disable subtitles"
|
||||
msgstr "Desativar legendas"
|
||||
|
||||
@@ -2055,11 +2055,11 @@ msgstr "Desativar legendas"
|
||||
msgid "Disabled"
|
||||
msgstr "Desabilitado"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:839
|
||||
#: src/view/com/composer/Composer.tsx:843
|
||||
msgid "Discard"
|
||||
msgstr "Descartar"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:836
|
||||
#: src/view/com/composer/Composer.tsx:840
|
||||
msgid "Discard draft?"
|
||||
msgstr "Descartar rascunho?"
|
||||
|
||||
@@ -2089,7 +2089,7 @@ msgstr "Descubra Novos Feeds"
|
||||
#~ msgid "Dismiss"
|
||||
#~ msgstr "Ocultar"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:1106
|
||||
#: src/view/com/composer/Composer.tsx:1110
|
||||
msgid "Dismiss error"
|
||||
msgstr "Ocultar erro"
|
||||
|
||||
@@ -2141,8 +2141,8 @@ msgstr "Domínio verificado!"
|
||||
#: src/screens/Onboarding/StepProfile/index.tsx:325
|
||||
#: src/view/com/auth/server-input/index.tsx:169
|
||||
#: src/view/com/auth/server-input/index.tsx:170
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:167
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:177
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:171
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:181
|
||||
#: src/view/com/modals/AddAppPasswords.tsx:243
|
||||
#: src/view/com/modals/AltImage.tsx:141
|
||||
#: src/view/com/modals/crop-image/CropImage.web.tsx:177
|
||||
@@ -2417,7 +2417,7 @@ msgstr "Habilitar mídia para"
|
||||
msgid "Enable priority notifications"
|
||||
msgstr "Habilitar notificações prioritárias"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:336
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:380
|
||||
msgid "Enable subtitles"
|
||||
msgstr "Habilitar legendas"
|
||||
|
||||
@@ -2447,7 +2447,7 @@ msgstr "Fim do feed"
|
||||
#~ msgid "End of onboarding tour window. Do not move forward. Instead, go backward for more options, or press to skip."
|
||||
#~ msgstr "Fim da integração da sua janela. Não avance. Em vez disso, volte para mais opções ou pressione para pular."
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:157
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:161
|
||||
msgid "Ensure you have selected a language for each subtitle file."
|
||||
msgstr "Certifique-se de ter selecionado um idioma para cada arquivo de legenda."
|
||||
|
||||
@@ -2549,7 +2549,7 @@ msgstr "Excluir usuário que você segue"
|
||||
msgid "Excludes users you follow"
|
||||
msgstr "Excluir usuário que você segue"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:353
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:397
|
||||
msgid "Exit fullscreen"
|
||||
msgstr "Sair da tela cheia"
|
||||
|
||||
@@ -3057,7 +3057,7 @@ msgctxt "from-feed"
|
||||
msgid "From <0/>"
|
||||
msgstr "Por <0/>"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:354
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:398
|
||||
msgid "Fullscreen"
|
||||
msgstr "Tela cheia"
|
||||
|
||||
@@ -3526,7 +3526,7 @@ msgstr "Convites, mas pessoais"
|
||||
msgid "It's just you right now! Add more people to your starter pack by searching above."
|
||||
msgstr "É só você por enquanto! Adicione mais pessoas ao seu pacote inicial pesquisando acima."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:1125
|
||||
#: src/view/com/composer/Composer.tsx:1129
|
||||
msgid "Job ID: {0}"
|
||||
msgstr ""
|
||||
|
||||
@@ -4046,15 +4046,15 @@ msgstr "Filmes"
|
||||
msgid "Music"
|
||||
msgstr "Música"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:345
|
||||
msgctxt "video"
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
msgid "Mute"
|
||||
msgstr "Silenciar"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:389
|
||||
msgctxt "video"
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.web.tsx:116
|
||||
msgid "Mute {truncatedTag}"
|
||||
msgstr "Silenciar {truncatedTag}"
|
||||
@@ -4583,7 +4583,7 @@ msgstr "Resetar tutoriais"
|
||||
#~ msgid "Onboarding tour step {0}: {1}"
|
||||
#~ msgstr "Etapa do tour de integração {0}: {1}"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:668
|
||||
#: src/view/com/composer/Composer.tsx:672
|
||||
msgid "One or more images is missing alt text."
|
||||
msgstr "Uma ou mais imagens estão sem texto alternativo."
|
||||
|
||||
@@ -4638,8 +4638,8 @@ msgid "Open conversation options"
|
||||
msgstr "Abrir opções de conversa"
|
||||
|
||||
#: src/screens/Messages/Conversation/MessageInput.web.tsx:165
|
||||
#: src/view/com/composer/Composer.tsx:819
|
||||
#: src/view/com/composer/Composer.tsx:820
|
||||
#: src/view/com/composer/Composer.tsx:823
|
||||
#: src/view/com/composer/Composer.tsx:824
|
||||
msgid "Open emoji picker"
|
||||
msgstr "Abrir seletor de emojis"
|
||||
|
||||
@@ -4825,7 +4825,7 @@ msgstr "Abre as preferências de threads"
|
||||
msgid "Opens this profile"
|
||||
msgstr "Abre este perfil"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:81
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:88
|
||||
msgid "Opens video picker"
|
||||
msgstr "Abre seletor de vídeos"
|
||||
|
||||
@@ -4903,11 +4903,11 @@ msgid "Password updated!"
|
||||
msgstr "Senha atualizada!"
|
||||
|
||||
#: src/view/com/util/post-embeds/GifEmbed.tsx:44
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:322
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:366
|
||||
msgid "Pause"
|
||||
msgstr "Pausar"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:275
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:319
|
||||
msgid "Pause video"
|
||||
msgstr "Pausar vídeo"
|
||||
|
||||
@@ -4967,7 +4967,7 @@ msgid "Pinned to your feeds"
|
||||
msgstr "Fixado em seus feeds"
|
||||
|
||||
#: src/view/com/util/post-embeds/GifEmbed.tsx:44
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:323
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:367
|
||||
msgid "Play"
|
||||
msgstr "Tocar"
|
||||
|
||||
@@ -4984,8 +4984,8 @@ msgstr "Reproduzir {0}"
|
||||
msgid "Play or pause the GIF"
|
||||
msgstr "Tocar ou pausar o GIF"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:187
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:276
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.tsx:189
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:320
|
||||
msgid "Play video"
|
||||
msgstr "Reproduzir vídeo"
|
||||
|
||||
@@ -5057,7 +5057,7 @@ msgstr "Por favor entre como @{0}"
|
||||
msgid "Please Verify Your Email"
|
||||
msgstr "Por favor, verifique seu e-mail"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:356
|
||||
#: src/view/com/composer/Composer.tsx:360
|
||||
msgid "Please wait for your link card to finish loading"
|
||||
msgstr "Aguarde até que a prévia de link termine de carregar"
|
||||
|
||||
@@ -5070,8 +5070,8 @@ msgstr "Política"
|
||||
msgid "Porn"
|
||||
msgstr "Pornografia"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:643
|
||||
#: src/view/com/composer/Composer.tsx:650
|
||||
#: src/view/com/composer/Composer.tsx:647
|
||||
#: src/view/com/composer/Composer.tsx:654
|
||||
msgctxt "action"
|
||||
msgid "Post"
|
||||
msgstr "Postar"
|
||||
@@ -5250,11 +5250,11 @@ msgstr "Listas públicas e compartilháveis para silenciar ou bloquear usuários
|
||||
msgid "Public, shareable lists which can drive feeds."
|
||||
msgstr "Listas públicas e compartilháveis que geram feeds."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:628
|
||||
#: src/view/com/composer/Composer.tsx:632
|
||||
msgid "Publish post"
|
||||
msgstr "Publicar post"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:628
|
||||
#: src/view/com/composer/Composer.tsx:632
|
||||
msgid "Publish reply"
|
||||
msgstr "Publicar resposta"
|
||||
|
||||
@@ -5482,7 +5482,7 @@ msgstr "Remover citação"
|
||||
msgid "Remove repost"
|
||||
msgstr "Desfazer repost"
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:260
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:264
|
||||
msgid "Remove subtitle file"
|
||||
msgstr "Remover arquivo de legenda"
|
||||
|
||||
@@ -5559,7 +5559,7 @@ msgstr "Respostas para esta postagem estão desativadas."
|
||||
#~ msgid "Replies to this thread are disabled"
|
||||
#~ msgstr "Respostas para esta thread estão desativadas"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:641
|
||||
#: src/view/com/composer/Composer.tsx:645
|
||||
msgctxt "action"
|
||||
msgid "Reply"
|
||||
msgstr "Responder"
|
||||
@@ -6053,7 +6053,7 @@ msgstr "Veja o guia"
|
||||
#~ msgid "See what's next"
|
||||
#~ msgstr "Veja o que vem por aí"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:587
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:631
|
||||
msgid "Seek slider"
|
||||
msgstr "Controle deslizante de busca"
|
||||
|
||||
@@ -6093,7 +6093,7 @@ msgstr "Selecionar GIF \"{0}\""
|
||||
msgid "Select how long to mute this word for."
|
||||
msgstr "Selecione por quanto tempo essa palavra deve ser silenciada."
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:245
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:249
|
||||
msgid "Select language..."
|
||||
msgstr "Selecione o idioma..."
|
||||
|
||||
@@ -6133,7 +6133,7 @@ msgstr "Selecione o serviço que hospeda seus dados."
|
||||
#~ msgid "Select topical feeds to follow from the list below"
|
||||
#~ msgstr "Selecione feeds de assuntos para seguir"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:80
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:87
|
||||
msgid "Select video"
|
||||
msgstr "Selecione o vídeo"
|
||||
|
||||
@@ -7429,7 +7429,7 @@ msgstr "Para desabilitar o 2FA via e-mail, por favor verifique seu acesso a este
|
||||
msgid "To report a conversation, please report one of its messages via the conversation screen. This lets our moderators understand the context of your issue."
|
||||
msgstr "Para denunciar uma conversa, por favor, denuncie uma das mensagens individualmente. Isso vai permitir a análise da situação pelos nossos moderadores."
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:106
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:113
|
||||
msgid "To upload videos to Bluesky, you must first verify your email."
|
||||
msgstr "Para enviar vídeos para o Bluesky, você deve primeiro verificar seu e-mail."
|
||||
|
||||
@@ -7572,16 +7572,16 @@ msgstr "Deixar de seguir"
|
||||
msgid "Unlike this feed"
|
||||
msgstr "Descurtir este feed"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:344
|
||||
msgctxt "video"
|
||||
msgid "Unmute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.tsx:263
|
||||
#: src/view/screens/ProfileList.tsx:689
|
||||
msgid "Unmute"
|
||||
msgstr "Dessilenciar"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:388
|
||||
msgctxt "video"
|
||||
msgid "Unmute"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/TagMenu/index.web.tsx:115
|
||||
msgid "Unmute {truncatedTag}"
|
||||
msgstr "Dessilenciar {truncatedTag}"
|
||||
@@ -7608,7 +7608,7 @@ msgstr "Desmutar conversa"
|
||||
msgid "Unmute thread"
|
||||
msgstr "Dessilenciar thread"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:273
|
||||
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx:317
|
||||
msgid "Unmute video"
|
||||
msgstr "Desmutar vídeo"
|
||||
|
||||
@@ -7837,7 +7837,7 @@ msgstr "Usuários que curtiram este conteúdo ou perfil"
|
||||
msgid "Value:"
|
||||
msgstr "Conteúdo:"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:104
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:111
|
||||
msgid "Verified email required"
|
||||
msgstr "E-mail verificado necessário"
|
||||
|
||||
@@ -7870,7 +7870,7 @@ msgstr "Verificar Meu Email"
|
||||
msgid "Verify New Email"
|
||||
msgstr "Verificar Novo E-mail"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:108
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:115
|
||||
msgid "Verify now"
|
||||
msgstr "Verifique agora"
|
||||
|
||||
@@ -7904,11 +7904,11 @@ msgstr "Falha no processamento do vídeo"
|
||||
msgid "Video Games"
|
||||
msgstr "Games"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:163
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:164
|
||||
msgid "Video not found."
|
||||
msgstr "Vídeo não encontrado."
|
||||
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:99
|
||||
#: src/view/com/composer/videos/SubtitleDialog.tsx:101
|
||||
msgid "Video settings"
|
||||
msgstr "Configurações de vídeo"
|
||||
|
||||
@@ -7920,6 +7920,11 @@ msgstr ""
|
||||
#~ msgid "Videos cannot be larger than 50MB"
|
||||
#~ msgstr "Vídeos não podem ter mais de 100 MB"
|
||||
|
||||
#: src/view/com/composer/videos/SelectVideoBtn.tsx:58
|
||||
#: src/view/com/composer/videos/VideoPreview.web.tsx:44
|
||||
msgid "Videos must be less than 60 seconds long"
|
||||
msgstr "Os vídeos devem ter menos de 60 segundos de duração."
|
||||
|
||||
#: src/screens/Profile/Header/Shell.tsx:113
|
||||
msgid "View {0}'s avatar"
|
||||
msgstr "Ver o avatar de {0}"
|
||||
@@ -8093,7 +8098,7 @@ msgstr "Não foi possível carregar sua lista de palavras silenciadas. Por favor
|
||||
msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
|
||||
msgstr "Lamentamos, mas sua busca não pôde ser concluída. Por favor, tente novamente em alguns minutos."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:418
|
||||
#: src/view/com/composer/Composer.tsx:422
|
||||
msgid "We're sorry! The post you are replying to has been deleted."
|
||||
msgstr "Sentimos muito! A postagem que você está respondendo foi excluída."
|
||||
|
||||
@@ -8132,7 +8137,7 @@ msgstr "Como você quer chamar seu pacote inicial?"
|
||||
|
||||
#: src/view/com/auth/SplashScreen.tsx:40
|
||||
#: src/view/com/auth/SplashScreen.web.tsx:86
|
||||
#: src/view/com/composer/Composer.tsx:513
|
||||
#: src/view/com/composer/Composer.tsx:517
|
||||
msgid "What's up?"
|
||||
msgstr "E aí?"
|
||||
|
||||
@@ -8207,11 +8212,11 @@ msgstr "Largo"
|
||||
msgid "Write a message"
|
||||
msgstr "Escreva uma mensagem"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:709
|
||||
#: src/view/com/composer/Composer.tsx:713
|
||||
msgid "Write post"
|
||||
msgstr "Escrever post"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:512
|
||||
#: src/view/com/composer/Composer.tsx:516
|
||||
#: src/view/com/post-thread/PostThreadComposePrompt.tsx:42
|
||||
msgid "Write your reply"
|
||||
msgstr "Escreva sua resposta"
|
||||
@@ -8571,7 +8576,7 @@ msgstr "O repositório da sua conta, contendo todos os seus dados públicos, pod
|
||||
msgid "Your birth date"
|
||||
msgstr "Sua data de nascimento"
|
||||
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:167
|
||||
#: src/view/com/util/post-embeds/VideoEmbed.web.tsx:168
|
||||
msgid "Your browser does not support the video format. Please try a different browser."
|
||||
msgstr "Seu navegador não suporta o formato de vídeo. Por favor, tente um navegador diferente."
|
||||
|
||||
@@ -8626,7 +8631,7 @@ msgstr "Suas palavras silenciadas"
|
||||
msgid "Your password has been changed successfully!"
|
||||
msgstr "Sua senha foi alterada com sucesso!"
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:464
|
||||
#: src/view/com/composer/Composer.tsx:468
|
||||
msgid "Your post has been published"
|
||||
msgstr "Seu post foi publicado"
|
||||
|
||||
@@ -8642,7 +8647,7 @@ msgstr "Seu perfil"
|
||||
msgid "Your profile, posts, feeds, and lists will no longer be visible to other Bluesky users. You can reactivate your account at any time by logging in."
|
||||
msgstr "Seu perfil, postagens, feeds e listas não serão mais visíveis para outros usuários do Bluesky. Você pode reativar sua conta a qualquer momento fazendo login."
|
||||
|
||||
#: src/view/com/composer/Composer.tsx:463
|
||||
#: src/view/com/composer/Composer.tsx:467
|
||||
msgid "Your reply has been published"
|
||||
msgstr "Sua resposta foi publicada"
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ export function StepInfo({
|
||||
defaultValue={state.password}
|
||||
secureTextEntry
|
||||
autoComplete="new-password"
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
</TextField.Root>
|
||||
</View>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import zod from 'zod'
|
||||
|
||||
import {BaseNux} from '#/state/queries/nuxs/types'
|
||||
|
||||
export enum Nux {
|
||||
One = 'one',
|
||||
Two = 'two',
|
||||
}
|
||||
|
||||
export const nuxNames = new Set(Object.values(Nux))
|
||||
|
||||
export type AppNux =
|
||||
| BaseNux<{
|
||||
id: Nux.One
|
||||
data: {
|
||||
likes: number
|
||||
}
|
||||
}>
|
||||
| BaseNux<{
|
||||
id: Nux.Two
|
||||
data: undefined
|
||||
}>
|
||||
|
||||
export const NuxSchemas = {
|
||||
[Nux.One]: zod.object({
|
||||
likes: zod.number(),
|
||||
}),
|
||||
[Nux.Two]: undefined,
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {AppNux, Nux} from '#/state/queries/nuxs/definitions'
|
||||
import {parseAppNux, serializeAppNux} from '#/state/queries/nuxs/util'
|
||||
import {
|
||||
preferencesQueryKey,
|
||||
usePreferencesQuery,
|
||||
} from '#/state/queries/preferences'
|
||||
import {useAgent} from '#/state/session'
|
||||
|
||||
export {Nux} from '#/state/queries/nuxs/definitions'
|
||||
|
||||
export function useNuxs() {
|
||||
const {data, ...rest} = usePreferencesQuery()
|
||||
|
||||
if (data && rest.isSuccess) {
|
||||
const nuxs = data.bskyAppState.nuxs
|
||||
?.map(parseAppNux)
|
||||
?.filter(Boolean) as AppNux[]
|
||||
|
||||
if (nuxs) {
|
||||
return {
|
||||
nuxs,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
nuxs: undefined,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
|
||||
export function useNux<T extends Nux>(id: T) {
|
||||
const {nuxs, ...rest} = useNuxs()
|
||||
|
||||
if (nuxs && rest.isSuccess) {
|
||||
const nux = nuxs.find(nux => nux.id === id)
|
||||
|
||||
if (nux) {
|
||||
return {
|
||||
nux: nux as Extract<AppNux, {id: T}>,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
nux: undefined,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
|
||||
export function useUpsertNuxMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (nux: AppNux) => {
|
||||
await agent.bskyAppUpsertNux(serializeAppNux(nux))
|
||||
// triggers a refetch
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: preferencesQueryKey,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useRemoveNuxsMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (ids: string[]) => {
|
||||
await agent.bskyAppRemoveNuxs(ids)
|
||||
// triggers a refetch
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: preferencesQueryKey,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import {AppBskyActorDefs} from '@atproto/api'
|
||||
|
||||
export type Data = Record<string, unknown> | undefined
|
||||
|
||||
export type BaseNux<
|
||||
T extends Pick<AppBskyActorDefs.Nux, 'id' | 'expiresAt'> & {data: Data},
|
||||
> = T & {
|
||||
completed: boolean
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import {AppBskyActorDefs, nuxSchema} from '@atproto/api'
|
||||
|
||||
import {
|
||||
AppNux,
|
||||
Nux,
|
||||
nuxNames,
|
||||
NuxSchemas,
|
||||
} from '#/state/queries/nuxs/definitions'
|
||||
|
||||
export function parseAppNux(nux: AppBskyActorDefs.Nux): AppNux | undefined {
|
||||
if (!nuxNames.has(nux.id as Nux)) return
|
||||
if (!nuxSchema.safeParse(nux).success) return
|
||||
|
||||
const {data, ...rest} = nux
|
||||
|
||||
const schema = NuxSchemas[nux.id as Nux]
|
||||
|
||||
if (schema && data) {
|
||||
const parsedData = JSON.parse(data)
|
||||
|
||||
if (!schema.safeParse(parsedData).success) return
|
||||
|
||||
return {
|
||||
...rest,
|
||||
data: parsedData,
|
||||
} as AppNux
|
||||
}
|
||||
|
||||
return {
|
||||
...rest,
|
||||
data: undefined,
|
||||
} as AppNux
|
||||
}
|
||||
|
||||
export function serializeAppNux(nux: AppNux): AppBskyActorDefs.Nux {
|
||||
const {data, ...rest} = nux
|
||||
const schema = NuxSchemas[nux.id as Nux]
|
||||
|
||||
const result: AppBskyActorDefs.Nux = {
|
||||
...rest,
|
||||
data: undefined,
|
||||
}
|
||||
|
||||
if (schema) {
|
||||
schema.parse(data)
|
||||
result.data = JSON.stringify(data)
|
||||
}
|
||||
|
||||
nuxSchema.parse(result)
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -37,5 +37,6 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
|
||||
bskyAppState: {
|
||||
queuedNudges: [],
|
||||
activeProgressGuide: undefined,
|
||||
nuxs: [],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -303,9 +303,13 @@ export const ComposePost = observer(function ComposePost({
|
||||
const onPhotoPasted = useCallback(
|
||||
async (uri: string) => {
|
||||
track('Composer:PastedPhotos')
|
||||
if (uri.startsWith('data:video/')) {
|
||||
selectVideo({uri, type: 'video', height: 0, width: 0})
|
||||
} else {
|
||||
await gallery.paste(uri)
|
||||
}
|
||||
},
|
||||
[gallery, track],
|
||||
[gallery, track, selectVideo],
|
||||
)
|
||||
|
||||
const isAltTextRequiredAndMissing = useMemo(() => {
|
||||
|
||||
@@ -93,9 +93,9 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
||||
}
|
||||
}, [onPressPublish])
|
||||
React.useEffect(() => {
|
||||
textInputWebEmitter.addListener('photo-pasted', onPhotoPasted)
|
||||
textInputWebEmitter.addListener('media-pasted', onPhotoPasted)
|
||||
return () => {
|
||||
textInputWebEmitter.removeListener('photo-pasted', onPhotoPasted)
|
||||
textInputWebEmitter.removeListener('media-pasted', onPhotoPasted)
|
||||
}
|
||||
}, [onPhotoPasted])
|
||||
|
||||
@@ -105,8 +105,8 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
||||
if (transfer) {
|
||||
const items = transfer.items
|
||||
|
||||
getImageFromUri(items, (uri: string) => {
|
||||
textInputWebEmitter.emit('photo-pasted', uri)
|
||||
getImageOrVideoFromUri(items, (uri: string) => {
|
||||
textInputWebEmitter.emit('media-pasted', uri)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
||||
view.pasteText(text)
|
||||
preventDefault = true
|
||||
}
|
||||
getImageFromUri(clipboardData.items, (uri: string) => {
|
||||
textInputWebEmitter.emit('photo-pasted', uri)
|
||||
getImageOrVideoFromUri(clipboardData.items, (uri: string) => {
|
||||
textInputWebEmitter.emit('media-pasted', uri)
|
||||
})
|
||||
if (preventDefault) {
|
||||
// Return `true` to prevent ProseMirror's default paste behavior.
|
||||
@@ -346,7 +346,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
})
|
||||
|
||||
function getImageFromUri(
|
||||
function getImageOrVideoFromUri(
|
||||
items: DataTransferItemList,
|
||||
callback: (uri: string) => void,
|
||||
) {
|
||||
@@ -363,11 +363,21 @@ function getImageFromUri(
|
||||
if (blob.type.startsWith('image/')) {
|
||||
blobToDataUri(blob).then(callback, err => console.error(err))
|
||||
}
|
||||
|
||||
if (blob.type.startsWith('video/')) {
|
||||
blobToDataUri(blob).then(callback, err => console.error(err))
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (type.startsWith('image/')) {
|
||||
const file = item.getAsFile()
|
||||
|
||||
if (file) {
|
||||
blobToDataUri(file).then(callback, err => console.error(err))
|
||||
}
|
||||
} else if (type.startsWith('video/')) {
|
||||
const file = item.getAsFile()
|
||||
|
||||
if (file) {
|
||||
blobToDataUri(file).then(callback, err => console.error(err))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import {Button} from '#/components/Button'
|
||||
import {VideoClip_Stroke2_Corner0_Rounded as VideoClipIcon} from '#/components/icons/VideoClip'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
|
||||
const VIDEO_MAX_DURATION = 60
|
||||
const VIDEO_MAX_DURATION = 60 * 1000 // 60s in milliseconds
|
||||
|
||||
type Props = {
|
||||
onSelectVideo: (video: ImagePickerAsset) => void
|
||||
@@ -45,13 +45,20 @@ export function SelectVideoBtn({onSelectVideo, disabled, setError}: Props) {
|
||||
const response = await launchImageLibraryAsync({
|
||||
exif: false,
|
||||
mediaTypes: MediaTypeOptions.Videos,
|
||||
videoMaxDuration: VIDEO_MAX_DURATION,
|
||||
quality: 1,
|
||||
legacy: true,
|
||||
preferredAssetRepresentationMode:
|
||||
UIImagePickerPreferredAssetRepresentationMode.Current,
|
||||
})
|
||||
if (response.assets && response.assets.length > 0) {
|
||||
if (isNative) {
|
||||
if (typeof response.assets[0].duration !== 'number')
|
||||
throw Error('Asset is not a video')
|
||||
if (response.assets[0].duration > VIDEO_MAX_DURATION) {
|
||||
setError(_(msg`Videos must be less than 60 seconds long`))
|
||||
return
|
||||
}
|
||||
}
|
||||
try {
|
||||
onSelectVideo(response.assets[0])
|
||||
} catch (err) {
|
||||
|
||||
@@ -12,6 +12,8 @@ import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||
|
||||
const MAX_DURATION = 60
|
||||
|
||||
export function VideoPreview({
|
||||
asset,
|
||||
video,
|
||||
@@ -36,6 +38,15 @@ export function VideoPreview({
|
||||
'loadedmetadata',
|
||||
function () {
|
||||
setDimensions(this.videoWidth, this.videoHeight)
|
||||
if (!isNaN(this.duration)) {
|
||||
if (this.duration > MAX_DURATION) {
|
||||
Toast.show(
|
||||
_(msg`Videos must be less than 60 seconds long`),
|
||||
'xmark',
|
||||
)
|
||||
clear()
|
||||
}
|
||||
}
|
||||
},
|
||||
{signal},
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ import {useAutoplayDisabled} from 'state/preferences'
|
||||
import {VideoEmbedInnerNative} from '#/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {useIsWithinMessage} from '#/components/dms/MessageContext'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||
import {VisibilityView} from '../../../../../modules/expo-bluesky-swiss-army'
|
||||
@@ -68,7 +69,8 @@ function InnerWrapper({embed}: Props) {
|
||||
const [isMuted, setIsMuted] = useState(player.muted)
|
||||
const [isFullscreen, setIsFullscreen] = React.useState(false)
|
||||
const [timeRemaining, setTimeRemaining] = React.useState(0)
|
||||
const disableAutoplay = useAutoplayDisabled()
|
||||
const isWithinMessage = useIsWithinMessage()
|
||||
const disableAutoplay = useAutoplayDisabled() || isWithinMessage
|
||||
const isActive = embed.playlist === activeSource && activeViewId === viewId
|
||||
// There are some different loading states that we should pay attention to and show a spinner for
|
||||
const isLoading =
|
||||
|
||||
@@ -4,14 +4,15 @@ import {AppBskyEmbedVideo} from '@atproto/api'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isFirefox} from '#/lib/browser'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {
|
||||
HLSUnsupportedError,
|
||||
VideoEmbedInnerWeb,
|
||||
VideoNotFoundError,
|
||||
} from '#/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {useIsWithinMessage} from '#/components/dms/MessageContext'
|
||||
import {useFullscreen} from '#/components/hooks/useFullscreen'
|
||||
import {ErrorBoundary} from '../ErrorBoundary'
|
||||
import {useActiveVideoWeb} from './ActiveVideoWebContext'
|
||||
@@ -19,13 +20,14 @@ import * as VideoFallback from './VideoEmbedInner/VideoFallback'
|
||||
|
||||
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const gate = useGate()
|
||||
const {active, setActive, sendPosition, currentActiveView} =
|
||||
useActiveVideoWeb()
|
||||
const [onScreen, setOnScreen] = useState(false)
|
||||
const [isFullscreen] = useFullscreen()
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current) return
|
||||
if (isFullscreen && !isFirefox) return
|
||||
const observer = new IntersectionObserver(
|
||||
entries => {
|
||||
const entry = entries[0]
|
||||
@@ -39,7 +41,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||
)
|
||||
observer.observe(ref.current)
|
||||
return () => observer.disconnect()
|
||||
}, [sendPosition])
|
||||
}, [sendPosition, isFullscreen])
|
||||
|
||||
const [key, setKey] = useState(0)
|
||||
const renderError = useCallback(
|
||||
@@ -49,10 +51,6 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||
[key],
|
||||
)
|
||||
|
||||
if (!gate('video_view_on_posts')) {
|
||||
return null
|
||||
}
|
||||
|
||||
let aspectRatio = 16 / 9
|
||||
|
||||
if (embed.aspectRatio) {
|
||||
@@ -103,17 +101,18 @@ function ViewportObserver({
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
sendPosition: (position: number) => void
|
||||
isAnyViewActive?: boolean
|
||||
isAnyViewActive: boolean
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const [nearScreen, setNearScreen] = useState(false)
|
||||
const [isFullscreen] = useFullscreen()
|
||||
const [nearScreenOrFullscreen, setNearScreenOrFullscreen] = useState(false)
|
||||
const isWithinMessage = useIsWithinMessage()
|
||||
|
||||
// Send position when scrolling. This is done with an IntersectionObserver
|
||||
// observing a div of 100vh height
|
||||
useEffect(() => {
|
||||
if (!ref.current) return
|
||||
if (isFullscreen && !isFirefox) return
|
||||
const observer = new IntersectionObserver(
|
||||
entries => {
|
||||
const entry = entries[0]
|
||||
@@ -127,7 +126,7 @@ function ViewportObserver({
|
||||
)
|
||||
observer.observe(ref.current)
|
||||
return () => observer.disconnect()
|
||||
}, [sendPosition])
|
||||
}, [sendPosition, isFullscreen])
|
||||
|
||||
// In case scrolling hasn't started yet, send up the position
|
||||
useEffect(() => {
|
||||
@@ -138,24 +137,18 @@ function ViewportObserver({
|
||||
}
|
||||
}, [isAnyViewActive, sendPosition])
|
||||
|
||||
// disguesting effect - it should be `nearScreen` except when fullscreen
|
||||
// when it should be whatever it was before fullscreen changed
|
||||
useEffect(() => {
|
||||
if (!isFullscreen) {
|
||||
setNearScreenOrFullscreen(nearScreen)
|
||||
}
|
||||
}, [isFullscreen, nearScreen])
|
||||
|
||||
return (
|
||||
<View style={[a.flex_1, a.flex_row]}>
|
||||
{nearScreenOrFullscreen && children}
|
||||
{nearScreen && children}
|
||||
<div
|
||||
ref={ref}
|
||||
style={{
|
||||
// Don't escape bounds when in a message
|
||||
...(isWithinMessage
|
||||
? {top: 0, height: '100%'}
|
||||
: {top: 'calc(50% - 50vh)', height: '100vh'}),
|
||||
position: 'absolute',
|
||||
top: 'calc(50% - 50vh)',
|
||||
left: '50%',
|
||||
height: '100vh',
|
||||
width: 1,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
|
||||
@@ -35,7 +35,13 @@ export function VideoEmbedInnerWeb({
|
||||
if (!ref.current) return
|
||||
if (!Hls.isSupported()) throw new HLSUnsupportedError()
|
||||
|
||||
const hls = new Hls({capLevelToPlayerSize: true})
|
||||
const hls = new Hls({
|
||||
capLevelToPlayerSize: true,
|
||||
maxMaxBufferLength: 10, // only load 10s ahead
|
||||
// note: the amount buffered is affected by both maxBufferLength and maxBufferSize
|
||||
// it will buffer until it it's greater than *both* of those values
|
||||
// so we use maxMaxBufferLength to set the actual maximum amount of buffering instead
|
||||
})
|
||||
hlsRef.current = hls
|
||||
|
||||
hls.attachMedia(ref.current)
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from '#/state/preferences'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {useIsWithinMessage} from '#/components/dms/MessageContext'
|
||||
import {useFullscreen} from '#/components/hooks/useFullscreen'
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
import {
|
||||
@@ -95,6 +96,15 @@ export function Controls({
|
||||
}
|
||||
}, [interactingViaKeypress])
|
||||
|
||||
useEffect(() => {
|
||||
if (isFullscreen) {
|
||||
document.documentElement.style.scrollbarGutter = 'unset'
|
||||
return () => {
|
||||
document.documentElement.style.removeProperty('scrollbar-gutter')
|
||||
}
|
||||
}
|
||||
}, [isFullscreen])
|
||||
|
||||
// pause + unfocus when another video is active
|
||||
useEffect(() => {
|
||||
if (!active) {
|
||||
@@ -104,7 +114,8 @@ export function Controls({
|
||||
}, [active, pause, setFocused])
|
||||
|
||||
// autoplay/pause based on visibility
|
||||
const autoplayDisabled = useAutoplayDisabled()
|
||||
const isWithinMessage = useIsWithinMessage()
|
||||
const autoplayDisabled = useAutoplayDisabled() || isWithinMessage
|
||||
useEffect(() => {
|
||||
if (active) {
|
||||
if (onScreen) {
|
||||
@@ -121,8 +132,12 @@ export function Controls({
|
||||
if (focused) {
|
||||
// auto decide quality based on network conditions
|
||||
hlsRef.current.autoLevelCapping = -1
|
||||
// allow 30s of buffering
|
||||
hlsRef.current.config.maxMaxBufferLength = 30
|
||||
} else {
|
||||
// back to what we initially set
|
||||
hlsRef.current.autoLevelCapping = 0
|
||||
hlsRef.current.config.maxMaxBufferLength = 10
|
||||
}
|
||||
}, [hlsRef, focused])
|
||||
|
||||
@@ -235,6 +250,39 @@ export function Controls({
|
||||
}
|
||||
}, [])
|
||||
|
||||
// these are used to trigger the hover state. on mobile, the hover state
|
||||
// should stick around for a bit after they tap, and if the controls aren't
|
||||
// present this initial tab should *only* show the controls and not activate anything
|
||||
|
||||
const onPointerDown = useCallback(
|
||||
(evt: React.PointerEvent<HTMLDivElement>) => {
|
||||
if (evt.pointerType !== 'mouse' && !hovered) {
|
||||
evt.preventDefault()
|
||||
}
|
||||
},
|
||||
[hovered],
|
||||
)
|
||||
|
||||
const timeoutRef = useRef<ReturnType<typeof setTimeout>>()
|
||||
|
||||
const onHoverWithTimeout = useCallback(() => {
|
||||
onHover()
|
||||
clearTimeout(timeoutRef.current)
|
||||
}, [onHover])
|
||||
|
||||
const onEndHoverWithTimeout = useCallback(
|
||||
(evt: React.PointerEvent<HTMLDivElement>) => {
|
||||
// if touch, end after 3s
|
||||
// if mouse, end immediately
|
||||
if (evt.pointerType !== 'mouse') {
|
||||
setTimeout(onEndHover, 3000)
|
||||
} else {
|
||||
onEndHover()
|
||||
}
|
||||
},
|
||||
[onEndHover],
|
||||
)
|
||||
|
||||
const showControls =
|
||||
((focused || autoplayDisabled) && !playing) ||
|
||||
(interactingViaKeypress ? hasFocus : hovered)
|
||||
@@ -252,9 +300,10 @@ export function Controls({
|
||||
evt.stopPropagation()
|
||||
setInteractingViaKeypress(false)
|
||||
}}
|
||||
onPointerEnter={onHover}
|
||||
onPointerMove={onHover}
|
||||
onPointerLeave={onEndHover}
|
||||
onPointerEnter={onHoverWithTimeout}
|
||||
onPointerMove={onHoverWithTimeout}
|
||||
onPointerLeave={onEndHoverWithTimeout}
|
||||
onPointerDown={onPointerDown}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onKeyDown={onKeyDown}>
|
||||
@@ -543,7 +592,7 @@ function Scrubber({
|
||||
return (
|
||||
<View
|
||||
testID="scrubber"
|
||||
style={[{height: 10, width: '100%'}, a.flex_shrink_0, a.px_xs]}
|
||||
style={[{height: 18, width: '100%'}, a.flex_shrink_0, a.px_xs, a.py_xs]}
|
||||
onPointerEnter={onStartHover}
|
||||
onPointerLeave={onEndHover}>
|
||||
<div
|
||||
|
||||
@@ -72,19 +72,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@atproto-labs/simple-store/-/simple-store-0.1.1.tgz#e743a2722b5d8732166f0a72aca8bd10e9bff106"
|
||||
integrity sha512-WKILW2b3QbAYKh+w5U2x6p5FqqLl0nAeLwGeDY+KjX01K4Dq3vQTR9b/qNp0jZm48CabPQVrqCv0PPU9LgRRRg==
|
||||
|
||||
"@atproto/api@0.13.5":
|
||||
version "0.13.5"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.5.tgz#04305cdb0a467ba366305c5e95cebb7ce0d39735"
|
||||
integrity sha512-yT/YimcKYkrI0d282Zxo7O30OSYR+KDW89f81C6oYZfDRBcShC1aniVV8kluP5LrEAg8O27yrOSnBgx2v7XPew==
|
||||
dependencies:
|
||||
"@atproto/common-web" "^0.3.0"
|
||||
"@atproto/lexicon" "^0.4.1"
|
||||
"@atproto/syntax" "^0.3.0"
|
||||
"@atproto/xrpc" "^0.6.1"
|
||||
await-lock "^2.2.2"
|
||||
multiformats "^9.9.0"
|
||||
tlds "^1.234.0"
|
||||
|
||||
"@atproto/api@^0.13.0":
|
||||
version "0.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.0.tgz#d1c65a407f1c3c6aba5be9425f4f739a01419bd8"
|
||||
@@ -98,6 +85,20 @@
|
||||
multiformats "^9.9.0"
|
||||
tlds "^1.234.0"
|
||||
|
||||
"@atproto/api@^0.13.7":
|
||||
version "0.13.7"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.7.tgz#072eba2025d5251505f17b0b5d2de33749ea5ee4"
|
||||
integrity sha512-41kSLmFWDbuPOenb52WRq1lnBkSZrL+X29tWcvEt6SZXK4xBoKAalw1MjF+oabhzff12iMtNaNvmmt2fu1L+cw==
|
||||
dependencies:
|
||||
"@atproto/common-web" "^0.3.0"
|
||||
"@atproto/lexicon" "^0.4.1"
|
||||
"@atproto/syntax" "^0.3.0"
|
||||
"@atproto/xrpc" "^0.6.2"
|
||||
await-lock "^2.2.2"
|
||||
multiformats "^9.9.0"
|
||||
tlds "^1.234.0"
|
||||
zod "^3.23.8"
|
||||
|
||||
"@atproto/aws@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.2.tgz#703e5e06f288bcf61c6d99a990738f1e7299e653"
|
||||
@@ -443,10 +444,10 @@
|
||||
"@atproto/lexicon" "^0.4.1"
|
||||
zod "^3.23.8"
|
||||
|
||||
"@atproto/xrpc@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.1.tgz#dcd1315c8c60eef5af2db7fa4e35a38ebc6d79d5"
|
||||
integrity sha512-Zy5ydXEdk6sY7FDUZcEVfCL1jvbL4tXu5CcdPqbEaW6LQtk9GLds/DK1bCX9kswTGaBC88EMuqQMfkxOhp2t4A==
|
||||
"@atproto/xrpc@^0.6.2":
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.2.tgz#634228a7e533de01bda2214837d11574fdadad55"
|
||||
integrity sha512-as/gb08xJb02HAGNrSQSumCe10WnOAcnM6bR6KMatQyQJuEu7OY6ZDSTM/4HfjjoxsNqdvPmbYuoUab1bKTNlA==
|
||||
dependencies:
|
||||
"@atproto/lexicon" "^0.4.1"
|
||||
zod "^3.23.8"
|
||||
|
||||
Reference in New Issue
Block a user