├── .nvmrc ├── .watchmanconfig ├── .ruby-version ├── bskyweb ├── static │ ├── ips-v6 │ ├── css │ │ └── .gitkeep │ ├── media │ │ ├── .gitkeep │ │ ├── InterVariable.c9f788f6e7ebaec75d7c.ttf │ │ ├── MaterialIcons.f20305dee9d396fea5c7.ttf │ │ ├── InterVariable.c504db5c06caaf7cdfba.woff2 │ │ ├── InterVariable-Italic.55d6a3f35e9b605ba6f4.ttf │ │ └── InterVariable-Italic.01dcbad1bac635f9c9cd.woff2 │ ├── js │ │ └── .gitkeep │ ├── favicon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── apple-touch-icon.png │ ├── social-card-default.png │ ├── social-card-default-gradient.png │ ├── robots-disallow-all.txt │ ├── .well-known │ │ ├── security.txt │ │ ├── apple-app-site-association │ │ └── assetlinks.json │ └── robots.txt ├── embedr-static │ ├── ips-v6 │ ├── embed.js │ ├── iframe-resize.js │ ├── favicon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── .well-known │ │ └── security.txt │ └── robots.txt ├── cmd │ ├── bskyweb │ │ └── .gitignore │ └── embedr │ │ ├── .gitignore │ │ └── render.go ├── embedr-templates │ ├── error.html │ ├── postEmbed.html │ ├── oembed.html │ └── home.html ├── example.dev.env ├── example.env ├── static.go └── templates.go ├── src ├── lib │ ├── media │ │ ├── avatar-generator.tsx │ │ └── video │ │ │ ├── types.ts │ │ │ └── errors.ts │ ├── hooks │ │ ├── useOTAUpdates.web.ts │ │ ├── useWebScrollRestoration.native.ts │ │ ├── useColorSchemeStyle.ts │ │ ├── useAnimatedValue.ts │ │ ├── useAppState.ts │ │ ├── useDedupe.ts │ │ └── useBottomBarOffset.ts │ ├── strings │ │ ├── constants.ts │ │ ├── capitalize.ts │ │ ├── headings.ts │ │ ├── bidi.ts │ │ └── email.ts │ ├── broadcast │ │ ├── index.ts │ │ ├── index.web.ts │ │ └── stub.ts │ ├── batchedUpdates.ts │ ├── batchedUpdates.web.ts │ ├── build-flags.ts │ ├── async │ │ ├── timeout.ts │ │ ├── wait.ts │ │ └── cancelable.ts │ ├── numbers.ts │ ├── browser.native.ts │ ├── custom-animations │ │ └── GestureActionView.web.tsx │ ├── assets.native.ts │ ├── statsig │ │ └── gates.ts │ ├── assets.ts │ ├── moderation │ │ └── blocked-and-muted.ts │ ├── notifications │ │ └── notifications.e2e.ts │ ├── browser.ts │ ├── type-guards.ts │ └── canvas.ts ├── logger │ ├── bitdrift │ │ ├── setup │ │ │ └── index.web.ts │ │ └── lib │ │ │ ├── index.ts │ │ │ └── index.web.ts │ ├── sentry │ │ └── lib │ │ │ ├── index.ts │ │ │ └── index.web.ts │ └── logDump.ts ├── view │ ├── com │ │ ├── util │ │ │ ├── Toast.e2e.tsx │ │ │ ├── Alert.tsx │ │ │ ├── fab │ │ │ │ ├── FAB.tsx │ │ │ │ └── FAB.web.tsx │ │ │ ├── images │ │ │ │ ├── Image.web.tsx │ │ │ │ └── Image.tsx │ │ │ ├── post-embeds │ │ │ │ ├── VideoEmbedInner │ │ │ │ │ ├── web-controls │ │ │ │ │ │ └── VideoControls.native.tsx │ │ │ │ │ ├── VideoEmbedInnerNative.web.tsx │ │ │ │ │ └── VideoEmbedInnerWeb.native.tsx │ │ │ │ └── types.ts │ │ │ ├── numeric │ │ │ │ └── format.ts │ │ │ └── LoadingScreen.tsx │ │ ├── modals │ │ │ ├── util.web.tsx │ │ │ └── util.tsx │ │ ├── testing │ │ │ └── TestCtrls.tsx │ │ ├── composer │ │ │ ├── photos │ │ │ │ ├── OpenCameraBtn.web.tsx │ │ │ │ └── EditImageDialog.tsx │ │ │ ├── text-input │ │ │ │ └── textInputWebEmitter.ts │ │ │ └── videos │ │ │ │ ├── SubtitleFilePicker.native.tsx │ │ │ │ └── VideoTranscodeBackdrop.web.tsx │ │ ├── home │ │ │ └── HomeHeaderLayout.tsx │ │ └── posts │ │ │ └── AviFollowButton.web.tsx │ ├── screens │ │ └── Search │ │ │ └── index.tsx │ └── shell │ │ └── BlockDrawerGesture.tsx ├── components │ ├── dms │ │ ├── dialogs │ │ │ ├── TextInput.web.tsx │ │ │ └── TextInput.tsx │ │ ├── EmojiPopup.tsx │ │ └── MessageContext.tsx │ ├── FullWindowOverlay.tsx │ ├── FullWindowOverlay.ios.tsx │ ├── ReportDialog │ │ ├── const.ts │ │ └── types.ts │ ├── moderation │ │ └── ReportDialog │ │ │ └── const.ts │ ├── Layout │ │ └── context.ts │ ├── SubtleWebHover.tsx │ ├── ProfileHoverCard │ │ ├── index.tsx │ │ └── types.ts │ ├── icons │ │ ├── DotGrid.tsx │ │ ├── Loader.tsx │ │ ├── Bars.tsx │ │ ├── Crop.tsx │ │ ├── MagnifyingGlass2.tsx │ │ ├── Menu.tsx │ │ ├── ArrowTriangle.tsx │ │ ├── Calendar.tsx │ │ ├── SquareBehindSquare4.tsx │ │ ├── Flag.tsx │ │ ├── TextSize.tsx │ │ ├── Clock.tsx │ │ ├── Phone.tsx │ │ ├── MagnifyingGlass.tsx │ │ ├── Growth.tsx │ │ ├── Leaf.tsx │ │ ├── PaperPlane.tsx │ │ ├── Times.tsx │ │ ├── CircleInfo.tsx │ │ ├── VideoClip.tsx │ │ ├── PageText.tsx │ │ ├── FloppyDisk.tsx │ │ ├── SquareArrowTopRight.tsx │ │ ├── Filter.tsx │ │ ├── Download.tsx │ │ ├── Window.tsx │ │ ├── ArrowOutOfBox.tsx │ │ ├── EditBig.tsx │ │ ├── Moon.tsx │ │ ├── SettingsSlider.tsx │ │ ├── CircleBanSign.tsx │ │ ├── Clipboard.tsx │ │ ├── FilterTimeline.tsx │ │ ├── EnveopeOpen.tsx │ │ ├── ArrowRotateCounterClockwise.tsx │ │ ├── Plus.tsx │ │ ├── Trending2.tsx │ │ ├── Zap.tsx │ │ ├── CircleX.tsx │ │ ├── CodeLines.tsx │ │ ├── Mute.tsx │ │ ├── PaintRoller.tsx │ │ ├── ListMagnifyingGlass.tsx │ │ ├── PeopleRemove2.tsx │ │ ├── GameController.tsx │ │ ├── Macintosh.tsx │ │ ├── Warning.tsx │ │ ├── Image.tsx │ │ ├── News2.tsx │ │ ├── CalendarDays.tsx │ │ ├── BubbleInfo.tsx │ │ ├── CircleQuestion.tsx │ │ └── StreamingLive.tsx │ ├── forms │ │ └── DateField │ │ │ ├── utils.ts │ │ │ └── types.ts │ ├── Fill.tsx │ ├── ContextMenu │ │ └── index.web.tsx │ ├── hooks │ │ ├── useOnKeyboard.ts │ │ ├── useRefreshOnFocus.ts │ │ └── useInteractionState.ts │ ├── Divider.tsx │ └── Dialog │ │ └── utils.ts ├── screens │ ├── VideoFeed │ │ ├── index.web.tsx │ │ └── types.ts │ ├── Login │ │ ├── ScreenTransition.web.tsx │ │ └── ScreenTransition.tsx │ ├── Settings │ │ ├── AppIconSettings │ │ │ ├── SettingsListItem.web.tsx │ │ │ ├── index.web.tsx │ │ │ └── types.ts │ │ └── components │ │ │ └── OTAInfo.web.tsx │ └── Profile │ │ ├── Sections │ │ └── types.ts │ │ └── Header │ │ └── StatusBarShadow.web.tsx ├── alf │ └── util │ │ ├── flatten.ts │ │ └── themeSelector.ts ├── state │ ├── messages │ │ ├── events │ │ │ └── const.ts │ │ └── convo │ │ │ └── const.ts │ ├── queries │ │ ├── messages │ │ │ └── const.ts │ │ ├── threadgate │ │ │ └── types.ts │ │ ├── nuxs │ │ │ ├── types.ts │ │ │ └── definitions.ts │ │ └── index.ts │ ├── shell │ │ ├── reminders.e2e.ts │ │ └── post-progress.tsx │ ├── cache │ │ └── types.ts │ ├── preferences │ │ └── dev-mode.ts │ ├── persisted │ │ └── types.ts │ └── session │ │ └── agent-config.ts ├── platform │ ├── markBundleStartTime.web.ts │ └── crypto.ts ├── env.ts ├── types │ └── bsky │ │ ├── profile.ts │ │ └── starterPack.ts ├── locale │ └── i18nProvider.tsx ├── Splash.android.tsx └── storage │ └── schema.ts ├── .editorconfig ├── __e2e__ ├── config.yml ├── setupServer.js ├── setupApp.yml └── flows │ └── post-report-flow.yml ├── __mocks__ ├── react-native-fs.js ├── @miblanchard │ └── react-native-slider.js ├── expo-localization.js ├── sentry-expo.js ├── react-native-background-fetch.ts ├── zeego │ └── dropdown-menu.js ├── @notifee │ └── react-native.ts ├── rn-fetch-blob.js ├── @react-native-camera-roll │ └── camera-roll.js └── react-native-image-crop-picker.js ├── .bundle └── config ├── modules ├── expo-bluesky-gif-view │ ├── index.ts │ ├── android │ │ └── src │ │ │ └── main │ │ │ └── AndroidManifest.xml │ ├── expo-module.config.json │ └── src │ │ └── GifView.types.ts ├── bottom-sheet │ ├── android │ │ └── src │ │ │ └── main │ │ │ └── AndroidManifest.xml │ ├── src │ │ ├── BottomSheet.tsx │ │ ├── BottomSheet.web.tsx │ │ └── BottomSheetNativeComponent.web.tsx │ └── expo-module.config.json ├── expo-bluesky-swiss-army │ ├── android │ │ └── src │ │ │ └── main │ │ │ └── AndroidManifest.xml │ ├── src │ │ ├── VisibilityView │ │ │ ├── types.ts │ │ │ └── index.tsx │ │ ├── Referrer │ │ │ ├── types.ts │ │ │ ├── index.ts │ │ │ └── index.android.ts │ │ └── NotImplemented.ts │ ├── ios │ │ └── Referrer │ │ │ └── ExpoBlueskyReferrerModule.swift │ └── index.ts ├── expo-receive-android-intents │ ├── android │ │ ├── src │ │ │ └── main │ │ │ │ └── AndroidManifest.xml │ │ └── .gitignore │ ├── expo-module.config.json │ └── README.md ├── expo-background-notification-handler │ ├── android │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── expo │ │ │ └── modules │ │ │ └── backgroundnotificationhandler │ │ │ └── BackgroundNotificationHandlerInterface.kt │ ├── index.ts │ ├── expo-module.config.json │ └── src │ │ └── ExpoBackgroundNotificationHandlerModule.ts ├── expo-scroll-forwarder │ ├── index.ts │ ├── expo-module.config.json │ ├── src │ │ ├── ExpoScrollForwarder.types.ts │ │ ├── ExpoScrollForwarderView.tsx │ │ └── ExpoScrollForwarderView.ios.tsx │ └── ios │ │ └── ExpoScrollForwarderModule.swift ├── BlueskyClip │ └── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ ├── App-Icon-1024x1024@1x.png │ │ └── Contents.json ├── BlueskyNSE │ └── BlueskyNSE.entitlements └── Share-with-Bluesky │ └── Share-with-Bluesky.entitlements ├── assets ├── dm.aiff ├── dm.mp3 ├── kawaii.png ├── logo.png ├── splash.png ├── favicon.png ├── kawaii_smol.png ├── splash-dark.png ├── default-avatar.png ├── splash-android-icon.png ├── fonts │ └── inter │ │ ├── Inter-Black.otf │ │ ├── Inter-Bold.otf │ │ ├── Inter-Light.otf │ │ ├── Inter-Thin.otf │ │ ├── Inter-Black.woff2 │ │ ├── Inter-Bold.woff2 │ │ ├── Inter-Italic.otf │ │ ├── Inter-Italic.woff2 │ │ ├── Inter-Light.woff2 │ │ ├── Inter-Medium.otf │ │ ├── Inter-Medium.woff2 │ │ ├── Inter-Regular.otf │ │ ├── Inter-SemiBold.otf │ │ ├── Inter-Thin.woff2 │ │ ├── InterVariable.ttf │ │ ├── Inter-BoldItalic.otf │ │ ├── Inter-ExtraBold.otf │ │ ├── Inter-ExtraLight.otf │ │ ├── Inter-Regular.woff2 │ │ ├── Inter-SemiBold.woff2 │ │ ├── Inter-ThinItalic.otf │ │ ├── InterVariable.woff2 │ │ ├── Inter-BlackItalic.otf │ │ ├── Inter-BlackItalic.woff2 │ │ ├── Inter-BoldItalic.woff2 │ │ ├── Inter-ExtraBold.woff2 │ │ ├── Inter-ExtraLight.woff2 │ │ ├── Inter-LightItalic.otf │ │ ├── Inter-LightItalic.woff2 │ │ ├── Inter-MediumItalic.otf │ │ ├── Inter-ThinItalic.woff2 │ │ ├── Inter-ExtraBoldItalic.otf │ │ ├── Inter-MediumItalic.woff2 │ │ ├── Inter-SemiBoldItalic.otf │ │ ├── InterVariable-Italic.ttf │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ ├── Inter-ExtraLightItalic.otf │ │ ├── Inter-ExtraLightItalic.woff2 │ │ ├── Inter-SemiBoldItalic.woff2 │ │ └── InterVariable-Italic.woff2 ├── icon-android-background.png ├── icon-android-foreground.png ├── icon-android-notification.png ├── splash-android-icon-dark.png ├── app-icons │ ├── ios_icon_core_aurora.png │ ├── ios_icon_core_bonfire.png │ ├── ios_icon_core_classic.png │ ├── ios_icon_core_sunrise.png │ ├── ios_icon_core_sunset.png │ ├── ios_icon_default_dark.png │ ├── ios_icon_core_flat_blue.png │ ├── ios_icon_core_midnight.png │ ├── ios_icon_default_light.png │ ├── android_icon_core_aurora.png │ ├── android_icon_core_bonfire.png │ ├── android_icon_core_classic.png │ ├── android_icon_core_midnight.png │ ├── android_icon_core_sunrise.png │ ├── android_icon_core_sunset.png │ ├── android_icon_default_dark.png │ ├── android_icon_default_light.png │ ├── ios_icon_core_flat_black.png │ ├── ios_icon_core_flat_white.png │ ├── android_icon_core_flat_black.png │ ├── android_icon_core_flat_blue.png │ └── android_icon_core_flat_white.png └── icons │ ├── pause_filled_corner2_rounded.svg │ ├── play_filled_corner0_rounded.svg │ ├── bubble_filled_stroke2_corner2_rounded.svg │ ├── aspectRatio11_stroke2_corner0_rounded.svg │ ├── play_filled_corner2_rounded.svg │ ├── plusLarge_stroke2_corner0_rounded.svg │ ├── plusSmall_stroke2_corner0_rounded.svg │ ├── loader_stroke2_corner0_rounded.svg │ ├── pause_filled_corner0_rounded.svg │ ├── arrowTriangleBottom_stroke2_corner1_rounded.svg │ ├── homeOpen_filled_corner0_rounded.svg │ ├── chevronTop_stroke2_corner0_rounded.svg │ ├── dotGrid1x3Horizontal_stroke2_corner2_rounded.svg │ ├── arrowTopRight_stoke2_corner0_rounded.svg │ ├── chevronBottom_stroke2_corner0_rounded.svg │ ├── chevronLeft_stroke2_corner0_rounded.svg │ ├── chevronRight_stroke2_corner0_rounded.svg │ ├── play_stroke2_corner0_rounded.svg │ ├── check_stroke2_corner0_rounded.svg │ ├── magnifyingGlass2_stroke2_corner0_rounded.svg │ ├── arrowLeft_stroke2_corner0_rounded.svg │ ├── aspectRatio34_stroke2_corner0_rounded.svg │ ├── aspectRatio43_stroke2_corner0_rounded.svg │ ├── bars3_stroke2_corner0_rounded.svg │ ├── crop_stroke2_corner0_rounded.svg │ ├── arrowBottom_stroke2_corner0_rounded.svg │ ├── arrowRight_stroke2_corner0_rounded.svg │ ├── textSize_stroke2_corner0_rounded.svg │ ├── menu_stroke2_corner0_rounded.svg │ ├── calendar_stroke2_corner0_rounded.svg │ ├── envelope_filled_stroke2_corner0_rounded.svg │ ├── squareBehindSquare4_stroke2_corner0_rounded.svg │ ├── bulletList_filled_corner0_rounded.svg │ ├── checkThick_stroke2_corner0_rounded.svg │ ├── magnifyingGlass_filled_corner0_rounded.svg │ ├── pause_stroke2_corner0_rounded.svg │ ├── flag_stroke2_corner0_rounded.svg │ ├── pause_stroke2_corner2_rounded.svg │ ├── lock_stroke2_corner0_rounded.svg │ ├── pin_filled_stroke2_corner0_rounded.svg │ ├── clock_stroke2_corner0_rounded.svg │ ├── star_filled_corner0_rounded.svg │ ├── leaf_stroke2_corner0_rounded.svg │ ├── phone_stroke2_corner2_rounded.svg │ ├── camera_filled_stroke2_corner0_rounded.svg │ ├── growth_stroke2_corner0_rounded.svg │ ├── heart2_filled_stroke2_corner0_rounded.svg │ ├── paperPlane_stroke2_corner0_rounded.svg │ ├── timesLarge_stroke2_corner0_rounded.svg │ ├── circleInfo_stroke2_corner0_rounded.svg │ ├── squareArrowTopRight_stroke2_corner0_rounded.svg │ ├── userCircle_filled_corner0_rounded.svg │ ├── pageText_stroke2_corner0_rounded.svg │ ├── floppyDisk_stroke2_corner0_rounded.svg │ ├── bell_filled_corner0_rounded.svg │ ├── filter_stroke2_corner0_rounded.svg │ ├── homeOpen_stroke2_corner0_rounded.svg │ ├── pencil_stroke2_corner0_rounded.svg │ ├── play_stroke2_corner2_rounded.svg │ ├── bell2_filled_corner0_rounded.svg │ ├── chevronTopBottom_stroke2_corner0_rounded.svg │ ├── lock_stroke2_corner2_rounded.svg │ ├── pencilLine_stroke2_corner0_rounded.svg │ ├── videoClip_stroke2_corner0_rounded.svg │ ├── arrowOutOfBox_stroke2_corner0_rounded.svg │ ├── arrowsDiagonalOut_stroke2_corner0_rounded.svg │ ├── bubble_stroke2_corner3_rounded.svg │ ├── download_stroke2_corner0_rounded.svg │ ├── flipHorizontal_stroke2_corner0_rounded.svg │ ├── flipVertical_stroke2_corner0_rounded.svg │ ├── bubble_stroke2_corner2_rounded.svg │ ├── bulletList_stroke2_corner0_rounded.svg │ ├── settingsSliderVertical_stroke2_corner0_rounded.svg │ ├── window_stroke2_corner2_rounded.svg │ ├── arrowsDiagonalOut_stroke2_corner2_rounded.svg │ ├── editBig_stroke2_corner0_rounded.svg │ ├── arrowsDiagonalIn_stroke2_corner0_rounded.svg │ ├── arrowsDiagonalIn_stroke2_corner2_rounded.svg │ ├── moon_stroke2_corner2_rounded.svg │ ├── person_stroke2_corner0_rounded.svg │ ├── circleBanSign_stroke2_corner0_rounded.svg │ ├── arrowBoxLeft_stroke2_corner0_rounded.svg │ ├── arrowBoxLeft_stroke2_corner2_rounded.svg │ ├── arrowRotateCounterClockwise_stroke2_corner0_rounded.svg │ ├── clipboard_stroke2_corner2_rounded.svg │ ├── filterTimeline_stroke2_corner0_rounded.svg │ ├── personPlus_filled_stroke2_corner0_rounded.svg │ ├── cc_stroke2_corner0_rounded.svg │ ├── envelope_open_stroke2_corner0_rounded.svg │ ├── bell_stroke2_corner0_rounded.svg │ ├── cc_filled_stroke2_corner0_rounded.svg │ ├── repost_stroke2_corner0_rounded.svg │ ├── camera_stroke2_corner0_rounded.svg │ ├── message_stroke2_corner0_rounded_filled.svg │ ├── trending2_stroke2_corner2_rounded.svg │ ├── circleX_stroke2_corner0_rounded.svg │ ├── closeQuote_filled_stroke2_corner0_rounded.svg │ ├── mute_stroke2_corner0_rounded.svg │ ├── zap_stroke2_corner0_rounded.svg │ ├── codeLines_stroke2_corner2_rounded.svg │ ├── home_stroke2_corner2_rounded.svg │ ├── openQuote_filled_stroke2_corner0_rounded.svg │ ├── paintRoller_stroke2_corner2_rounded.svg │ ├── pin_stroke2_corner0_rounded.svg │ ├── bellOff_filled_corner0_rounded.svg │ ├── eye_stroke2_corner0_rounded.svg │ ├── listMagnifyingGlass_stroke2_corner0_rounded.svg │ ├── peopleRemove2_stroke2_corner0_rounded.svg │ ├── codeBrackets_stroke2_corner0_rounded.svg │ ├── repost_stroke2_corner2_rounded.svg │ ├── listPlus_stroke2_corner0_rounded.svg │ ├── gameController_stroke2_corner0_rounded.svg │ ├── trash_stroke2_corner0_rounded.svg │ ├── emojiArc_stroke2_corner0_rounded.svg │ ├── hashtag_stroke2_corner0_rounded.svg │ ├── macintosh_stroke2_corner2_rounded.svg │ ├── bell2_stroke2_corner0_rounded.svg │ ├── pencilLine_stroke2_corner2_rounded.svg │ ├── news2_stroke2_corner0_rounded.svg │ ├── personPlus_stroke2_corner0_rounded.svg │ ├── warning_stroke2_corner0_rounded.svg │ ├── circleQuestion_stroke2_corner2_rounded.svg │ ├── image_stroke2_corner0_rounded.svg │ ├── repost_stroke2_corner3_rounded.svg │ ├── calendarDays_stroke2_corner0_rounded.svg │ ├── bubbleInfo_stroke2_corner2_rounded.svg │ ├── bubbles_stroke2_corner2_rounded.svg │ ├── eye_stroke2_corner2_rounded.svg │ └── trash_stroke2_corner2_rounded.svg ├── bskyembed ├── .gitignore ├── postcss.config.cjs ├── tsconfig.snippet.json └── assets │ ├── play_filled_corner2_rounded.svg │ ├── bubble_filled_stroke2_corner2_rounded.svg │ ├── arrowBottom_stroke2_corner0_rounded.svg │ ├── heart2_filled_stroke2_corner0_rounded.svg │ ├── circleInfo_stroke2_corner0_rounded.svg │ └── repost_stroke2_corner2_rounded.svg ├── tsconfig.check.json ├── .husky └── pre-commit ├── docs └── img │ ├── ota-flow.png │ ├── run-workflow.png │ ├── app-build-number.png │ ├── branch-selection.png │ ├── slack-build-info.png │ └── other-ota-options.png ├── bskylink ├── src │ ├── db │ │ ├── migrations │ │ │ ├── index.ts │ │ │ └── provider.ts │ │ └── schema.ts │ ├── logger.ts │ ├── util.ts │ └── routes │ │ └── root.ts ├── tests │ └── infra │ │ └── with-test-db.sh └── tsconfig.json ├── bskyogcard ├── src │ ├── assets │ │ └── fonts │ │ │ └── Inter-Bold.ttf │ ├── logger.ts │ ├── components │ │ └── Img.tsx │ └── routes │ │ ├── health.ts │ │ └── index.ts └── tsconfig.json ├── .buckconfig ├── scripts ├── README.md ├── useBuildNumberEnv.sh ├── setGitHubOutput.sh └── useBuildNumberEnvWithBump.sh ├── patches ├── expo-modules-core+2.1.2.md ├── expo-updates+0.26.10.patch.md └── @lingui+core+4.14.1.patch ├── .prettierrc.js ├── index.web.js ├── .env.example ├── Gemfile ├── jest └── dev-infra │ ├── with-test-db.sh │ └── with-test-redis-and-db.sh ├── eslint └── index.js ├── .prettierignore ├── plugins ├── shareExtension │ └── withAppEntitlements.js ├── notificationsExtension │ └── withAppEntitlements.js └── withAndroidManifestPlugin.js ├── __tests__ └── lib │ └── link-meta.test.ts └── tsconfig.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.6 2 | -------------------------------------------------------------------------------- /bskyweb/static/ips-v6: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/ips-v6: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bskyweb/static/css/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bskyweb/static/media/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bskyweb/static/js/.gitkeep: -------------------------------------------------------------------------------- 1 | NOOP 2 | -------------------------------------------------------------------------------- /src/lib/media/avatar-generator.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/logger/bitdrift/setup/index.web.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bskyweb/cmd/bskyweb/.gitignore: -------------------------------------------------------------------------------- 1 | /bskyweb 2 | -------------------------------------------------------------------------------- /bskyweb/cmd/embedr/.gitignore: -------------------------------------------------------------------------------- 1 | /bskyweb 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{kt,kts}] 2 | indent_size=2 3 | -------------------------------------------------------------------------------- /__e2e__/config.yml: -------------------------------------------------------------------------------- 1 | flows: 2 | - "flows/**" 3 | -------------------------------------------------------------------------------- /__mocks__/react-native-fs.js: -------------------------------------------------------------------------------- 1 | export default {} 2 | -------------------------------------------------------------------------------- /bskyweb/embedr-templates/error.html: -------------------------------------------------------------------------------- 1 | placeholder! 2 | -------------------------------------------------------------------------------- /src/view/com/util/Toast.e2e.tsx: -------------------------------------------------------------------------------- 1 | export function show() {} 2 | -------------------------------------------------------------------------------- /src/view/com/util/Alert.tsx: -------------------------------------------------------------------------------- 1 | export {Alert} from 'react-native' 2 | -------------------------------------------------------------------------------- /bskyweb/embedr-templates/postEmbed.html: -------------------------------------------------------------------------------- 1 | embed post HTML will go here 2 | -------------------------------------------------------------------------------- /src/lib/hooks/useOTAUpdates.web.ts: -------------------------------------------------------------------------------- 1 | export function useOTAUpdates() {} 2 | -------------------------------------------------------------------------------- /__mocks__/@miblanchard/react-native-slider.js: -------------------------------------------------------------------------------- 1 | export const Slider = {} 2 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/embed.js: -------------------------------------------------------------------------------- 1 | /* embed javascript widget will go here */ 2 | -------------------------------------------------------------------------------- /bskyweb/embedr-templates/oembed.html: -------------------------------------------------------------------------------- 1 | oembed JSON response will go here 2 | -------------------------------------------------------------------------------- /src/lib/strings/constants.ts: -------------------------------------------------------------------------------- 1 | export const NON_BREAKING_SPACE = '\u00A0' 2 | -------------------------------------------------------------------------------- /src/view/com/util/fab/FAB.tsx: -------------------------------------------------------------------------------- 1 | export {FABInner as FAB} from './FABInner' 2 | -------------------------------------------------------------------------------- /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /modules/expo-bluesky-gif-view/index.ts: -------------------------------------------------------------------------------- 1 | export {GifView} from './src/GifView' 2 | -------------------------------------------------------------------------------- /src/logger/sentry/lib/index.ts: -------------------------------------------------------------------------------- 1 | export * as Sentry from '@sentry/react-native' 2 | -------------------------------------------------------------------------------- /assets/dm.aiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/dm.aiff -------------------------------------------------------------------------------- /assets/dm.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/dm.mp3 -------------------------------------------------------------------------------- /bskyembed/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | -------------------------------------------------------------------------------- /modules/bottom-sheet/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/dms/dialogs/TextInput.web.tsx: -------------------------------------------------------------------------------- 1 | export {TextInput} from 'react-native' 2 | -------------------------------------------------------------------------------- /src/logger/sentry/lib/index.web.ts: -------------------------------------------------------------------------------- 1 | export * as Sentry from '@sentry/react-native' 2 | -------------------------------------------------------------------------------- /src/view/com/modals/util.web.tsx: -------------------------------------------------------------------------------- 1 | export {ScrollView, TextInput} from 'react-native' 2 | -------------------------------------------------------------------------------- /__mocks__/expo-localization.js: -------------------------------------------------------------------------------- 1 | export const getLocales = jest.fn().mockResolvedValue([]) 2 | -------------------------------------------------------------------------------- /assets/kawaii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/kawaii.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/logo.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/splash.png -------------------------------------------------------------------------------- /bskyweb/embedr-static/iframe-resize.js: -------------------------------------------------------------------------------- 1 | /* script to resize embed ifame would go here? */ 2 | -------------------------------------------------------------------------------- /bskyweb/example.dev.env: -------------------------------------------------------------------------------- 1 | GOLOG_LOG_LEVEL=info 2 | ATP_APPVIEW_HOST=http://localhost:2584 3 | -------------------------------------------------------------------------------- /bskyweb/example.env: -------------------------------------------------------------------------------- 1 | GOLOG_LOG_LEVEL=info 2 | ATP_APPVIEW_HOST=https://public.api.bsky.app 3 | -------------------------------------------------------------------------------- /src/components/FullWindowOverlay.tsx: -------------------------------------------------------------------------------- 1 | export {Fragment as FullWindowOverlay} from 'react' 2 | -------------------------------------------------------------------------------- /src/components/dms/EmojiPopup.tsx: -------------------------------------------------------------------------------- 1 | export {EmojiPopup} from 'react-native-emoji-popup' 2 | -------------------------------------------------------------------------------- /src/screens/VideoFeed/index.web.tsx: -------------------------------------------------------------------------------- 1 | export function VideoFeed() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /src/view/com/testing/TestCtrls.tsx: -------------------------------------------------------------------------------- 1 | export function TestCtrls() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.check.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/favicon.png -------------------------------------------------------------------------------- /modules/expo-bluesky-gif-view/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/lib/broadcast/index.ts: -------------------------------------------------------------------------------- 1 | import Stub from '#/lib/broadcast/stub' 2 | export default Stub 3 | -------------------------------------------------------------------------------- /src/screens/Login/ScreenTransition.web.tsx: -------------------------------------------------------------------------------- 1 | export {Fragment as ScreenTransition} from 'react' 2 | -------------------------------------------------------------------------------- /src/view/screens/Search/index.tsx: -------------------------------------------------------------------------------- 1 | export {SearchScreen} from '#/view/screens/Search/Search' 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /__mocks__/sentry-expo.js: -------------------------------------------------------------------------------- 1 | jest.mock('sentry-expo', () => ({ 2 | init: () => jest.fn(), 3 | })) 4 | -------------------------------------------------------------------------------- /assets/kawaii_smol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/kawaii_smol.png -------------------------------------------------------------------------------- /assets/splash-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/splash-dark.png -------------------------------------------------------------------------------- /docs/img/ota-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/ota-flow.png -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/FullWindowOverlay.ios.tsx: -------------------------------------------------------------------------------- 1 | export {FullWindowOverlay} from 'react-native-screens' 2 | -------------------------------------------------------------------------------- /src/lib/batchedUpdates.ts: -------------------------------------------------------------------------------- 1 | export {unstable_batchedUpdates as batchedUpdates} from 'react-native' 2 | -------------------------------------------------------------------------------- /src/lib/batchedUpdates.web.ts: -------------------------------------------------------------------------------- 1 | export {unstable_batchedUpdates as batchedUpdates} from 'react-dom' 2 | -------------------------------------------------------------------------------- /src/logger/bitdrift/lib/index.ts: -------------------------------------------------------------------------------- 1 | export {debug, error, info, warn} from '@bitdrift/react-native' 2 | -------------------------------------------------------------------------------- /src/screens/Settings/AppIconSettings/SettingsListItem.web.tsx: -------------------------------------------------------------------------------- 1 | export function SettingsListItem() {} 2 | -------------------------------------------------------------------------------- /src/screens/Settings/components/OTAInfo.web.tsx: -------------------------------------------------------------------------------- 1 | export function OTAInfo() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /modules/expo-receive-android-intents/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/lib/build-flags.ts: -------------------------------------------------------------------------------- 1 | export const LOGIN_INCLUDE_DEV_SERVERS = true 2 | export const PWI_ENABLED = true 3 | -------------------------------------------------------------------------------- /src/screens/Profile/Sections/types.ts: -------------------------------------------------------------------------------- 1 | export interface SectionRef { 2 | scrollToTop: () => void 3 | } 4 | -------------------------------------------------------------------------------- /assets/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/default-avatar.png -------------------------------------------------------------------------------- /bskyweb/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/favicon.png -------------------------------------------------------------------------------- /docs/img/run-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/run-workflow.png -------------------------------------------------------------------------------- /modules/expo-background-notification-handler/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/index.ts: -------------------------------------------------------------------------------- 1 | export {ExpoScrollForwarderView} from './src/ExpoScrollForwarderView' 2 | -------------------------------------------------------------------------------- /src/components/ReportDialog/const.ts: -------------------------------------------------------------------------------- 1 | export const DMCA_LINK = 'https://bsky.social/about/support/copyright' 2 | -------------------------------------------------------------------------------- /src/view/com/composer/photos/OpenCameraBtn.web.tsx: -------------------------------------------------------------------------------- 1 | export function OpenCameraBtn() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /docs/img/app-build-number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/app-build-number.png -------------------------------------------------------------------------------- /docs/img/branch-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/branch-selection.png -------------------------------------------------------------------------------- /docs/img/slack-build-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/slack-build-info.png -------------------------------------------------------------------------------- /src/alf/util/flatten.ts: -------------------------------------------------------------------------------- 1 | import {StyleSheet} from 'react-native' 2 | 3 | export const flatten = StyleSheet.flatten 4 | -------------------------------------------------------------------------------- /src/screens/Profile/Header/StatusBarShadow.web.tsx: -------------------------------------------------------------------------------- 1 | export function StatusBarShadow() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /assets/splash-android-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/splash-android-icon.png -------------------------------------------------------------------------------- /bskyweb/static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/favicon-16x16.png -------------------------------------------------------------------------------- /bskyweb/static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/favicon-32x32.png -------------------------------------------------------------------------------- /docs/img/other-ota-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/docs/img/other-ota-options.png -------------------------------------------------------------------------------- /src/components/dms/dialogs/TextInput.tsx: -------------------------------------------------------------------------------- 1 | export {BottomSheetTextInput as TextInput} from '@discord/bottom-sheet/src' 2 | -------------------------------------------------------------------------------- /src/components/moderation/ReportDialog/const.ts: -------------------------------------------------------------------------------- 1 | export const DMCA_LINK = 'https://bsky.social/about/support/copyright' 2 | -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Black.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Black.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Bold.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Light.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Thin.otf -------------------------------------------------------------------------------- /assets/icon-android-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/icon-android-background.png -------------------------------------------------------------------------------- /assets/icon-android-foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/icon-android-foreground.png -------------------------------------------------------------------------------- /bskylink/src/db/migrations/index.ts: -------------------------------------------------------------------------------- 1 | import * as init from './001-init.js' 2 | 3 | export default { 4 | '001': init, 5 | } 6 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/embedr-static/favicon.png -------------------------------------------------------------------------------- /src/lib/hooks/useWebScrollRestoration.native.ts: -------------------------------------------------------------------------------- 1 | export function useWebScrollRestoration() { 2 | return undefined 3 | } 4 | -------------------------------------------------------------------------------- /src/view/com/home/HomeHeaderLayout.tsx: -------------------------------------------------------------------------------- 1 | export {HomeHeaderLayoutMobile as HomeHeaderLayout} from './HomeHeaderLayoutMobile' 2 | -------------------------------------------------------------------------------- /src/view/com/util/images/Image.web.tsx: -------------------------------------------------------------------------------- 1 | import {Image} from 'react-native' 2 | 3 | export const HighPriorityImage = Image 4 | -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Black.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Italic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Light.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Medium.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Medium.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Regular.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-SemiBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-SemiBold.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Thin.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/InterVariable.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/InterVariable.ttf -------------------------------------------------------------------------------- /assets/icon-android-notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/icon-android-notification.png -------------------------------------------------------------------------------- /assets/splash-android-icon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/splash-android-icon-dark.png -------------------------------------------------------------------------------- /bskyweb/static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/apple-touch-icon.png -------------------------------------------------------------------------------- /modules/bottom-sheet/src/BottomSheet.tsx: -------------------------------------------------------------------------------- 1 | export {BottomSheetNativeComponent as BottomSheet} from './BottomSheetNativeComponent' 2 | -------------------------------------------------------------------------------- /src/state/messages/events/const.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_POLL_INTERVAL = 60e3 2 | export const BACKGROUND_POLL_INTERVAL = 60e3 * 5 3 | -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-BoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-BoldItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraBold.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraLight.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ThinItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ThinItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/InterVariable.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/InterVariable.woff2 -------------------------------------------------------------------------------- /bskyembed/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/embedr-static/favicon-16x16.png -------------------------------------------------------------------------------- /bskyweb/embedr-static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/embedr-static/favicon-32x32.png -------------------------------------------------------------------------------- /bskyweb/static/social-card-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/social-card-default.png -------------------------------------------------------------------------------- /modules/BlueskyClip/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/async/timeout.ts: -------------------------------------------------------------------------------- 1 | export function timeout(ms: number): Promise { 2 | return new Promise(r => setTimeout(r, ms)) 3 | } 4 | -------------------------------------------------------------------------------- /src/lib/strings/capitalize.ts: -------------------------------------------------------------------------------- 1 | export function capitalize(str: string) { 2 | return str.charAt(0).toUpperCase() + str.slice(1) 3 | } 4 | -------------------------------------------------------------------------------- /__mocks__/react-native-background-fetch.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | configure: jest.fn().mockResolvedValue(0), 3 | finish: jest.fn(), 4 | } 5 | -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_aurora.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_aurora.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_bonfire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_bonfire.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_classic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_classic.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_sunrise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_sunrise.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_sunset.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_default_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_default_dark.png -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-BlackItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-BlackItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-BlackItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-BoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraLight.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-LightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-LightItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-LightItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-MediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-MediumItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ThinItalic.woff2 -------------------------------------------------------------------------------- /bskyogcard/src/assets/fonts/Inter-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyogcard/src/assets/fonts/Inter-Bold.ttf -------------------------------------------------------------------------------- /src/lib/numbers.ts: -------------------------------------------------------------------------------- 1 | export function clamp(v: number, min: number, max: number): number { 2 | return Math.min(max, Math.max(min, v)) 3 | } 4 | -------------------------------------------------------------------------------- /src/state/queries/messages/const.ts: -------------------------------------------------------------------------------- 1 | export const DM_SERVICE_HEADERS = { 2 | 'atproto-proxy': 'did:web:api.bsky.chat#bsky_chat', 3 | } 4 | -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_flat_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_flat_blue.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_midnight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_midnight.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_default_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_default_light.png -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraBoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraBoldItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-MediumItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-SemiBoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-SemiBoldItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/InterVariable-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/InterVariable-Italic.ttf -------------------------------------------------------------------------------- /src/screens/Settings/AppIconSettings/index.web.tsx: -------------------------------------------------------------------------------- 1 | export function AppIconSettingsScreen() { 2 | throw new Error('Not supported on web') 3 | } 4 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_aurora.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_aurora.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_bonfire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_bonfire.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_classic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_classic.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_midnight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_midnight.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_sunrise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_sunrise.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_sunset.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_default_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_default_dark.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_default_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_default_light.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_flat_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_flat_black.png -------------------------------------------------------------------------------- /assets/app-icons/ios_icon_core_flat_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/ios_icon_core_flat_white.png -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraLightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraLightItalic.otf -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/Inter-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/Inter-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inter/InterVariable-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/fonts/inter/InterVariable-Italic.woff2 -------------------------------------------------------------------------------- /bskyweb/static/social-card-default-gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/social-card-default-gradient.png -------------------------------------------------------------------------------- /src/platform/markBundleStartTime.web.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore Web-only. On RN, this is set by Metro. 2 | window.__BUNDLE_START_TIME__ = performance.now() 3 | -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_flat_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_flat_black.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_flat_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_flat_blue.png -------------------------------------------------------------------------------- /assets/app-icons/android_icon_core_flat_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/assets/app-icons/android_icon_core_flat_white.png -------------------------------------------------------------------------------- /src/lib/broadcast/index.web.ts: -------------------------------------------------------------------------------- 1 | import Stub from '#/lib/broadcast/stub' 2 | export default 'BroadcastChannel' in window ? window.BroadcastChannel : Stub 3 | -------------------------------------------------------------------------------- /src/logger/bitdrift/lib/index.web.ts: -------------------------------------------------------------------------------- 1 | export function debug() {} 2 | export function error() {} 3 | export function info() {} 4 | export function warn() {} 5 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | # Tool Scripts 2 | 3 | ## updateExtensions.sh 4 | 5 | Updates the extensions in `/modules` with the current iOS/Android project changes. 6 | -------------------------------------------------------------------------------- /src/view/com/composer/text-input/textInputWebEmitter.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'eventemitter3' 2 | 3 | export const textInputWebEmitter = new EventEmitter() 4 | -------------------------------------------------------------------------------- /__mocks__/zeego/dropdown-menu.js: -------------------------------------------------------------------------------- 1 | export const DropdownMenu = jest.fn().mockImplementation(() => {}) 2 | export const create = jest.fn().mockImplementation(() => {}) 3 | -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["ios"], 3 | "ios": { 4 | "modules": ["ExpoScrollForwarderModule"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/view/com/modals/util.tsx: -------------------------------------------------------------------------------- 1 | export { 2 | BottomSheetScrollView as ScrollView, 3 | BottomSheetTextInput as TextInput, 4 | } from '@discord/bottom-sheet/src' 5 | -------------------------------------------------------------------------------- /src/components/Layout/context.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const ScrollbarOffsetContext = React.createContext({ 4 | isWithinOffsetView: false, 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/browser.native.ts: -------------------------------------------------------------------------------- 1 | export const isSafari = false 2 | export const isFirefox = false 3 | export const isTouchDevice = true 4 | export const isAndroidWeb = false 5 | -------------------------------------------------------------------------------- /src/state/shell/reminders.e2e.ts: -------------------------------------------------------------------------------- 1 | export function shouldRequestEmailConfirmation() { 2 | return false 3 | } 4 | 5 | export function snoozeEmailConfirmationPrompt() {} 6 | -------------------------------------------------------------------------------- /bskyweb/static/media/InterVariable.c9f788f6e7ebaec75d7c.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/media/InterVariable.c9f788f6e7ebaec75d7c.ttf -------------------------------------------------------------------------------- /bskyweb/static/media/MaterialIcons.f20305dee9d396fea5c7.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/media/MaterialIcons.f20305dee9d396fea5c7.ttf -------------------------------------------------------------------------------- /src/components/SubtleWebHover.tsx: -------------------------------------------------------------------------------- 1 | import {ViewStyleProp} from '#/alf' 2 | 3 | export function SubtleWebHover({}: ViewStyleProp & {hover: boolean}) { 4 | return null 5 | } 6 | -------------------------------------------------------------------------------- /src/view/com/composer/videos/SubtitleFilePicker.native.tsx: -------------------------------------------------------------------------------- 1 | export function SubtitleFilePicker() { 2 | throw new Error('SubtitleFilePicker is a web-only component') 3 | } 4 | -------------------------------------------------------------------------------- /__e2e__/setupServer.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line 2 | http.post('http://localhost:1986/' + SERVER_PATH, { 3 | headers: {'Content-Type': 'text/plain'}, 4 | body: '', 5 | }) 6 | -------------------------------------------------------------------------------- /bskyweb/static/media/InterVariable.c504db5c06caaf7cdfba.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/media/InterVariable.c504db5c06caaf7cdfba.woff2 -------------------------------------------------------------------------------- /src/view/com/posts/AviFollowButton.web.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export function AviFollowButton({children}: {children: React.ReactNode}) { 4 | return children 5 | } 6 | -------------------------------------------------------------------------------- /bskyweb/static/media/InterVariable-Italic.55d6a3f35e9b605ba6f4.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/media/InterVariable-Italic.55d6a3f35e9b605ba6f4.ttf -------------------------------------------------------------------------------- /patches/expo-modules-core+2.1.2.md: -------------------------------------------------------------------------------- 1 | ## expo-modules-core Patch 2 | 3 | This patch fixes an issue where bitdrift's API stream gets blocked by the Expo interceptor used to power the devtools 4 | -------------------------------------------------------------------------------- /src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.native.tsx: -------------------------------------------------------------------------------- 1 | export function Controls() { 2 | throw new Error('VideoWebControls may not be used on native.') 3 | } 4 | -------------------------------------------------------------------------------- /bskylink/src/logger.ts: -------------------------------------------------------------------------------- 1 | import {subsystemLogger} from '@atproto/common' 2 | 3 | export const httpLogger = subsystemLogger('bskylink') 4 | export const dbLogger = subsystemLogger('bskylink:db') 5 | -------------------------------------------------------------------------------- /bskyweb/static.go: -------------------------------------------------------------------------------- 1 | package bskyweb 2 | 3 | import "embed" 4 | 5 | //go:embed static/* 6 | var StaticFS embed.FS 7 | 8 | //go:embed embedr-static/* 9 | var EmbedrStaticFS embed.FS 10 | -------------------------------------------------------------------------------- /bskyweb/static/media/InterVariable-Italic.01dcbad1bac635f9c9cd.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/bskyweb/static/media/InterVariable-Italic.01dcbad1bac635f9c9cd.woff2 -------------------------------------------------------------------------------- /modules/expo-background-notification-handler/index.ts: -------------------------------------------------------------------------------- 1 | import {BackgroundNotificationHandler} from './src/ExpoBackgroundNotificationHandlerModule' 2 | export default BackgroundNotificationHandler 3 | -------------------------------------------------------------------------------- /src/components/ProfileHoverCard/index.tsx: -------------------------------------------------------------------------------- 1 | import {ProfileHoverCardProps} from './types' 2 | 3 | export function ProfileHoverCard({children}: ProfileHoverCardProps) { 4 | return children 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/custom-animations/GestureActionView.web.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export function GestureActionView({children}: {children: React.ReactNode}) { 4 | return children 5 | } 6 | -------------------------------------------------------------------------------- /src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.web.tsx: -------------------------------------------------------------------------------- 1 | export function VideoEmbedInnerNative() { 2 | throw new Error('VideoEmbedInnerNative may not be used on web.') 3 | } 4 | -------------------------------------------------------------------------------- /src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.native.tsx: -------------------------------------------------------------------------------- 1 | export function VideoEmbedInnerWeb() { 2 | throw new Error('VideoEmbedInnerWeb may not be used on native.') 3 | } 4 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | arrowParens: 'avoid', 4 | bracketSameLine: true, 5 | bracketSpacing: false, 6 | singleQuote: true, 7 | trailingComma: 'all', 8 | } 9 | -------------------------------------------------------------------------------- /__mocks__/@notifee/react-native.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | requestPermission: jest.fn(), 3 | onForegroundEvent: jest.fn(), 4 | setBadgeCount: jest.fn(), 5 | displayNotification: jest.fn(), 6 | } 7 | -------------------------------------------------------------------------------- /bskyweb/static/robots-disallow-all.txt: -------------------------------------------------------------------------------- 1 | # This is an development or self-hosted instance of the bsky web app, and crawling has been disallowed by the operator team. 2 | User-Agent: * 3 | Disallow: / 4 | -------------------------------------------------------------------------------- /src/view/com/composer/videos/VideoTranscodeBackdrop.web.tsx: -------------------------------------------------------------------------------- 1 | export function clearThumbnailCache() { 2 | // no-op 3 | } 4 | 5 | export function VideoTranscodeBackdrop() { 6 | return null 7 | } 8 | -------------------------------------------------------------------------------- /bskyweb/templates.go: -------------------------------------------------------------------------------- 1 | package bskyweb 2 | 3 | import "embed" 4 | 5 | //go:embed templates/* 6 | var TemplateFS embed.FS 7 | 8 | //go:embed embedr-templates/* 9 | var EmbedrTemplateFS embed.FS 10 | -------------------------------------------------------------------------------- /src/lib/media/video/types.ts: -------------------------------------------------------------------------------- 1 | export type CompressedVideo = { 2 | uri: string 3 | mimeType: string 4 | size: number 5 | // web only, can fall back to uri if missing 6 | bytes?: ArrayBuffer 7 | } 8 | -------------------------------------------------------------------------------- /bskyogcard/src/logger.ts: -------------------------------------------------------------------------------- 1 | import {subsystemLogger} from '@atproto/common' 2 | 3 | export const httpLogger = subsystemLogger('bskyogcard') 4 | export const renderLogger = subsystemLogger('bskyogcard:render') 5 | -------------------------------------------------------------------------------- /bskyweb/embedr-templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

embed.bsky.app homepage

6 |

could redirect to bsky.app? or show a "create embed" widget? 7 | 8 | 9 | -------------------------------------------------------------------------------- /index.web.js: -------------------------------------------------------------------------------- 1 | import '#/platform/markBundleStartTime' 2 | import '#/platform/polyfills' 3 | 4 | import {registerRootComponent} from 'expo' 5 | 6 | import App from '#/App' 7 | 8 | registerRootComponent(App) 9 | -------------------------------------------------------------------------------- /__mocks__/rn-fetch-blob.js: -------------------------------------------------------------------------------- 1 | jest.mock('rn-fetch-blob', () => { 2 | return { 3 | __esModule: true, 4 | default: { 5 | fs: { 6 | unlink: jest.fn(), 7 | }, 8 | }, 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /modules/BlueskyClip/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-bluesky-social/main/modules/BlueskyClip/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/src/ExpoScrollForwarder.types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export interface ExpoScrollForwarderViewProps { 4 | scrollViewTag: number | null 5 | children: React.ReactNode 6 | } 7 | -------------------------------------------------------------------------------- /src/components/ProfileHoverCard/types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export type ProfileHoverCardProps = { 4 | children: React.ReactElement 5 | did: string 6 | inline?: boolean 7 | disable?: boolean 8 | } 9 | -------------------------------------------------------------------------------- /src/env.ts: -------------------------------------------------------------------------------- 1 | export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || '' 2 | export const LOG_LEVEL = (process.env.EXPO_PUBLIC_LOG_LEVEL || 'info') as 3 | | 'debug' 4 | | 'info' 5 | | 'warn' 6 | | 'error' 7 | -------------------------------------------------------------------------------- /src/lib/async/wait.ts: -------------------------------------------------------------------------------- 1 | export async function wait(delay: number, fn: T): Promise> { 2 | return await Promise.all([fn, new Promise(y => setTimeout(y, delay))]).then( 3 | arr => arr[0], 4 | ) 5 | } 6 | -------------------------------------------------------------------------------- /assets/icons/pause_filled_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/play_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-receive-android-intents/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["android"], 3 | "android": { 4 | "modules": ["xyz.blueskyweb.app.exporeceiveandroidintents.ExpoReceiveAndroidIntentsModule"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/strings/headings.ts: -------------------------------------------------------------------------------- 1 | export function bskyTitle(page: string, unreadCountLabel?: string) { 2 | const unreadPrefix = unreadCountLabel ? `(${unreadCountLabel}) ` : '' 3 | return `${unreadPrefix}${page} — Bluesky` 4 | } 5 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Copy this to `.env` and `.env.test` files 2 | 3 | BITDRIFT_API_KEY= 4 | SENTRY_AUTH_TOKEN= 5 | EXPO_PUBLIC_LOG_LEVEL=debug 6 | EXPO_PUBLIC_LOG_DEBUG= 7 | EXPO_PUBLIC_BUNDLE_IDENTIFIER= 8 | EXPO_PUBLIC_BUNDLE_DATE=0 9 | -------------------------------------------------------------------------------- /modules/bottom-sheet/src/BottomSheet.web.tsx: -------------------------------------------------------------------------------- 1 | import {BottomSheetViewProps} from './BottomSheet.types' 2 | 3 | export function BottomSheet(_: BottomSheetViewProps) { 4 | throw new Error('BottomSheet is not available on web') 5 | } 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby File.read(File.join(__dir__, '.ruby-version')).strip 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.3' -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/VisibilityView/types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | export interface VisibilityViewProps { 3 | children: React.ReactNode 4 | onChangeStatus: (isActive: boolean) => void 5 | enabled: boolean 6 | } 7 | -------------------------------------------------------------------------------- /bskyembed/tsconfig.snippet.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "target": "ES5", 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "strict": true, 7 | "outDir": "dist" 8 | }, 9 | "include": ["snippet"] 10 | } 11 | -------------------------------------------------------------------------------- /bskylink/src/util.ts: -------------------------------------------------------------------------------- 1 | import {randomBytes} from 'node:crypto' 2 | 3 | import {toString} from 'uint8arrays' 4 | 5 | // 40bit random id of 5-7 characters 6 | export const randomId = () => { 7 | return toString(randomBytes(5), 'base58btc') 8 | } 9 | -------------------------------------------------------------------------------- /bskyweb/static/.well-known/security.txt: -------------------------------------------------------------------------------- 1 | Contact: mailto:security@bsky.app 2 | Preferred-Languages: en 3 | Canonical: https://bsky.app/.well-known/security.txt 4 | Acknowledgements: https://github.com/bluesky-social/atproto/blob/main/CONTRIBUTORS.md 5 | -------------------------------------------------------------------------------- /src/state/queries/threadgate/types.ts: -------------------------------------------------------------------------------- 1 | export type ThreadgateAllowUISetting = 2 | | {type: 'everybody'} 3 | | {type: 'nobody'} 4 | | {type: 'mention'} 5 | | {type: 'following'} 6 | | {type: 'followers'} 7 | | {type: 'list'; list: string} 8 | -------------------------------------------------------------------------------- /modules/expo-receive-android-intents/android/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Android/IntelliJ 6 | # 7 | build/ 8 | .idea 9 | .gradle 10 | local.properties 11 | *.iml 12 | *.hprof 13 | 14 | # Bundle artifacts 15 | *.jsbundle 16 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/.well-known/security.txt: -------------------------------------------------------------------------------- 1 | Contact: mailto:security@bsky.app 2 | Preferred-Languages: en 3 | Canonical: https://bsky.app/.well-known/security.txt 4 | Acknowledgements: https://github.com/bluesky-social/atproto/blob/main/CONTRIBUTORS.md 5 | -------------------------------------------------------------------------------- /modules/bottom-sheet/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["ios", "android"], 3 | "ios": { 4 | "modules": ["BottomSheetModule"] 5 | }, 6 | "android": { 7 | "modules": ["expo.modules.bottomsheet.BottomSheetModule"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/assets.native.ts: -------------------------------------------------------------------------------- 1 | import {ImageRequireSource} from 'react-native' 2 | 3 | export const DEF_AVATAR: ImageRequireSource = require('../../assets/default-avatar.png') 4 | export const CLOUD_SPLASH: ImageRequireSource = require('../../assets/splash.png') 5 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/ios/Referrer/ExpoBlueskyReferrerModule.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | public class ExpoBlueskyReferrerModule: Module { 4 | public func definition() -> ModuleDefinition { 5 | Name("ExpoBlueskyReferrer") 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/screens/Settings/AppIconSettings/types.ts: -------------------------------------------------------------------------------- 1 | import {ImageSourcePropType} from 'react-native' 2 | 3 | export type AppIconSet = { 4 | id: string 5 | name: string 6 | iosImage: () => ImageSourcePropType 7 | androidImage: () => ImageSourcePropType 8 | } 9 | -------------------------------------------------------------------------------- /jest/dev-infra/with-test-db.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Example usage: 4 | # ./with-test-db.sh psql postgresql://pg:password@localhost:5433/postgres -c 'select 1;' 5 | 6 | dir=$(dirname $0) 7 | . ${dir}/_common.sh 8 | 9 | SERVICES="db_test" main "$@" 10 | -------------------------------------------------------------------------------- /bskylink/tests/infra/with-test-db.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Example usage: 4 | # ./with-test-db.sh psql postgresql://pg:password@localhost:5433/postgres -c 'select 1;' 5 | 6 | dir=$(dirname $0) 7 | . ${dir}/_common.sh 8 | 9 | SERVICES="db_test" main "$@" 10 | -------------------------------------------------------------------------------- /assets/icons/bubble_filled_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/bottom-sheet/src/BottomSheetNativeComponent.web.tsx: -------------------------------------------------------------------------------- 1 | import {BottomSheetViewProps} from './BottomSheet.types' 2 | 3 | export function BottomSheetNativeComponent(_: BottomSheetViewProps) { 4 | throw new Error('BottomSheetNativeComponent is not available on web') 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/hooks/useColorSchemeStyle.ts: -------------------------------------------------------------------------------- 1 | import {useTheme} from '#/lib/ThemeContext' 2 | 3 | export function useColorSchemeStyle(lightStyle: T, darkStyle: T) { 4 | const colorScheme = useTheme().colorScheme 5 | return colorScheme === 'dark' ? darkStyle : lightStyle 6 | } 7 | -------------------------------------------------------------------------------- /assets/icons/aspectRatio11_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/play_filled_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/DotGrid.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const DotGrid_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M2 12a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm16 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm-6-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Loader.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Loader_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 5a7 7 0 0 0-5.218 11.666A1 1 0 0 1 5.292 18a9 9 0 1 1 13.416 0 1 1 0 1 1-1.49-1.334A7 7 0 0 0 12 5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/plusLarge_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/plusSmall_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/play_filled_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/loader_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pause_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/bubble_filled_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-bluesky-gif-view/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["ios", "android", "web"], 3 | "ios": { 4 | "modules": ["ExpoBlueskyGifViewModule"] 5 | }, 6 | "android": { 7 | "modules": ["expo.modules.blueskygifview.ExpoBlueskyGifViewModule"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/Referrer/types.ts: -------------------------------------------------------------------------------- 1 | export type GooglePlayReferrerInfo = { 2 | installReferrer?: string 3 | clickTimestamp?: number 4 | installTimestamp?: number 5 | } 6 | 7 | export type ReferrerInfo = { 8 | referrer: string 9 | hostname: string 10 | } 11 | -------------------------------------------------------------------------------- /src/components/forms/DateField/utils.ts: -------------------------------------------------------------------------------- 1 | // we need the date in the form yyyy-MM-dd to pass to the input 2 | export function toSimpleDateString(date: Date | string): string { 3 | const _date = typeof date === 'string' ? new Date(date) : date 4 | return _date.toISOString().split('T')[0] 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/statsig/gates.ts: -------------------------------------------------------------------------------- 1 | export type Gate = 2 | // Keep this alphabetic please. 3 | | 'debug_show_feedcontext' 4 | | 'debug_subscriptions' 5 | | 'old_postonboarding' 6 | | 'onboarding_add_video_feed' 7 | | 'remove_show_latest_button' 8 | | 'test_gate_1' 9 | | 'test_gate_2' 10 | -------------------------------------------------------------------------------- /assets/icons/arrowTriangleBottom_stroke2_corner1_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/homeOpen_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/chevronTop_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/dotGrid1x3Horizontal_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskylink/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "esModuleInterop": true, 5 | "moduleResolution": "NodeNext", 6 | "outDir": "dist", 7 | "lib": ["ES2021.String"] 8 | }, 9 | "include": ["./src/index.ts", "./src/bin.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /assets/icons/arrowTopRight_stoke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/lib/assets.ts: -------------------------------------------------------------------------------- 1 | import {ImageRequireSource} from 'react-native' 2 | 3 | // @ts-ignore we need to pretend -prf 4 | export const DEF_AVATAR: ImageRequireSource = {uri: '/img/default-avatar.png'} 5 | // @ts-ignore we need to pretend -prf 6 | export const CLOUD_SPLASH: ImageRequireSource = {uri: '/img/splash.png'} 7 | -------------------------------------------------------------------------------- /src/state/cache/types.ts: -------------------------------------------------------------------------------- 1 | // This isn't a real property, but it prevents T being compatible with Shadow. 2 | declare const shadowTag: unique symbol 3 | export type Shadow = T & {[shadowTag]: true} 4 | 5 | export function castAsShadow(value: T): Shadow { 6 | return value as any as Shadow 7 | } 8 | -------------------------------------------------------------------------------- /src/state/preferences/dev-mode.ts: -------------------------------------------------------------------------------- 1 | import {device, useStorage} from '#/storage' 2 | 3 | export function useDevModeEnabled() { 4 | const [devModeEnabled = false, setDevModeEnabled] = useStorage(device, [ 5 | 'devMode', 6 | ]) 7 | 8 | return [devModeEnabled, setDevModeEnabled] as const 9 | } 10 | -------------------------------------------------------------------------------- /assets/icons/chevronBottom_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/chevronLeft_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/chevronRight_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/play_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyogcard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "NodeNext", 5 | "esModuleInterop": true, 6 | "moduleResolution": "NodeNext", 7 | "jsx": "react-jsx", 8 | "outDir": "dist" 9 | }, 10 | "include": ["./src/index.ts", "./src/bin.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /src/components/icons/Bars.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Bars3_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 5a1 1 0 0 0 0 2h18a1 1 0 1 0 0-2H3Zm-1 7a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/platform/crypto.ts: -------------------------------------------------------------------------------- 1 | // HACK 2 | // expo-modules-core tries to require('crypto') in uuid.web.js 3 | // and while it tries to detect web crypto before doing so, our 4 | // build fails when it tries to do this require. We use a babel 5 | // and tsconfig alias to direct it here 6 | // -prf 7 | export default crypto 8 | -------------------------------------------------------------------------------- /src/components/icons/Crop.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Crop_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M6 2a1 1 0 0 1 1 1v2h11a1 1 0 0 1 1 1v11h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2H6a1 1 0 0 1-1-1V7H3a1 1 0 0 1 0-2h2V3a1 1 0 0 1 1-1Zm1 5v10h10V7H7Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/MagnifyingGlass2.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const MagnifyingGlass2_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M11 5a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm-8 6a8 8 0 1 1 14.32 4.906l3.387 3.387a1 1 0 0 1-1.414 1.414l-3.387-3.387A8 8 0 0 1 3 11Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/state/queries/nuxs/types.ts: -------------------------------------------------------------------------------- 1 | import {AppBskyActorDefs} from '@atproto/api' 2 | 3 | export type Data = Record | undefined 4 | 5 | export type BaseNux< 6 | T extends Pick & {data: Data}, 7 | > = Pick & T 8 | -------------------------------------------------------------------------------- /assets/icons/check_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/magnifyingGlass2_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowLeft_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/aspectRatio34_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/aspectRatio43_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/bars3_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/crop_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Menu.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Menu_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M2 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm0 6a1 1 0 0 1 1-1h18a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/state/messages/convo/const.ts: -------------------------------------------------------------------------------- 1 | export const ACTIVE_POLL_INTERVAL = 4e3 2 | export const MESSAGE_SCREEN_POLL_INTERVAL = 30e3 3 | export const BACKGROUND_POLL_INTERVAL = 60e3 4 | export const INACTIVE_TIMEOUT = 60e3 * 5 5 | 6 | export const NETWORK_FAILURE_STATUSES = [ 7 | 1, 408, 425, 429, 500, 502, 503, 504, 522, 524, 8 | ] 9 | -------------------------------------------------------------------------------- /assets/icons/arrowBottom_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowRight_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/textSize_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/arrowBottom_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import {ExpoScrollForwarderViewProps} from './ExpoScrollForwarder.types' 4 | 5 | export function ExpoScrollForwarderView({ 6 | children, 7 | }: React.PropsWithChildren) { 8 | return children 9 | } 10 | -------------------------------------------------------------------------------- /src/components/icons/ArrowTriangle.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const ArrowTriangleBottom_Stroke2_Corner1_Rounded = createSinglePathSVG({ 4 | path: 'M4.213 6.886c-.673-1.35.334-2.889 1.806-2.889H17.98c1.472 0 2.479 1.539 1.806 2.89l-5.982 11.997c-.74 1.484-2.87 1.484-3.61 0L4.213 6.886Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Calendar.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Calendar_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M8 2a1 1 0 0 1 1 1v1h6V3a1 1 0 1 1 2 0v1h2a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2V3a1 1 0 0 1 1-1ZM5 6v3h14V6H5Zm14 5H5v8h14v-8Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/menu_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskylink/src/db/migrations/provider.ts: -------------------------------------------------------------------------------- 1 | import {Migration, MigrationProvider} from 'kysely' 2 | 3 | export class DbMigrationProvider implements MigrationProvider { 4 | constructor(private migrations: Record) {} 5 | async getMigrations(): Promise> { 6 | return this.migrations 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /bskylink/src/db/schema.ts: -------------------------------------------------------------------------------- 1 | import {Selectable} from 'kysely' 2 | 3 | export type DbSchema = { 4 | link: Link 5 | } 6 | 7 | export interface Link { 8 | id: string 9 | type: LinkType 10 | path: string 11 | } 12 | 13 | export enum LinkType { 14 | StarterPack = 1, 15 | } 16 | 17 | export type LinkEntry = Selectable 18 | -------------------------------------------------------------------------------- /bskyogcard/src/components/Img.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export function Img( 4 | props: Omit, 'src'> & {src: Buffer}, 5 | ) { 6 | const {src, ...others} = props 7 | return ( 8 | 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /__e2e__/setupApp.yml: -------------------------------------------------------------------------------- 1 | appId: xyz.blueskyweb.app 2 | --- 3 | - launchApp: 4 | appId: "xyz.blueskyweb.app" 5 | clearState: true 6 | - waitForAnimationToEnd 7 | - tapOn: "http://localhost:8081" 8 | - waitForAnimationToEnd 9 | - extendedWaitUntil: 10 | visible: "Continue" 11 | - swipe: 12 | from: "Bluesky" 13 | direction: DOWN 14 | -------------------------------------------------------------------------------- /__mocks__/@react-native-camera-roll/camera-roll.js: -------------------------------------------------------------------------------- 1 | export const CameraRoll = { 2 | getPhotos: jest.fn().mockResolvedValue({ 3 | edges: [ 4 | {node: {image: {uri: 'path/to/image1.jpg'}}}, 5 | {node: {image: {uri: 'path/to/image2.jpg'}}}, 6 | {node: {image: {uri: 'path/to/image3.jpg'}}}, 7 | ], 8 | }), 9 | } 10 | -------------------------------------------------------------------------------- /assets/icons/calendar_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/envelope_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/squareBehindSquare4_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /eslint/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | rules: { 5 | 'avoid-unwrapped-text': require('./avoid-unwrapped-text'), 6 | 'use-exact-imports': require('./use-exact-imports'), 7 | 'use-typed-gates': require('./use-typed-gates'), 8 | 'use-prefixed-imports': require('./use-prefixed-imports'), 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /modules/expo-background-notification-handler/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["ios", "android"], 3 | "ios": { 4 | "modules": ["ExpoBackgroundNotificationHandlerModule"] 5 | }, 6 | "android": { 7 | "modules": ["expo.modules.backgroundnotificationhandler.ExpoBackgroundNotificationHandlerModule"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/components/icons/SquareBehindSquare4.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const SquareBehindSquare4_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M8 8V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1h-5v5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h5Zm1 8a1 1 0 0 1-1-1v-5H4v10h10v-4H9Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/view/com/util/numeric/format.ts: -------------------------------------------------------------------------------- 1 | import {I18n} from '@lingui/core' 2 | 3 | export const formatCount = (i18n: I18n, num: number) => { 4 | return i18n.number(num, { 5 | notation: 'compact', 6 | maximumFractionDigits: 1, 7 | // @ts-expect-error - roundingMode not in the types 8 | roundingMode: 'trunc', 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /src/view/com/util/post-embeds/types.ts: -------------------------------------------------------------------------------- 1 | export enum PostEmbedViewContext { 2 | ThreadHighlighted = 'ThreadHighlighted', 3 | Feed = 'Feed', 4 | FeedEmbedRecordWithMedia = 'FeedEmbedRecordWithMedia', 5 | } 6 | 7 | export enum QuoteEmbedViewContext { 8 | FeedEmbedRecordWithMedia = PostEmbedViewContext.FeedEmbedRecordWithMedia, 9 | } 10 | -------------------------------------------------------------------------------- /assets/icons/bulletList_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/checkThick_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/Fill.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View} from 'react-native' 3 | 4 | import {atoms as a, ViewStyleProp} from '#/alf' 5 | 6 | export function Fill({ 7 | children, 8 | style, 9 | }: {children?: React.ReactNode} & ViewStyleProp) { 10 | return {children} 11 | } 12 | -------------------------------------------------------------------------------- /assets/icons/magnifyingGlass_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pause_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyweb/static/.well-known/apple-app-site-association: -------------------------------------------------------------------------------- 1 | { 2 | "applinks": { 3 | "details": [ 4 | { 5 | "appID": "B3LX46C5HS.xyz.blueskyweb.app", 6 | "paths": [ 7 | "*" 8 | ] 9 | } 10 | ] 11 | }, 12 | "appclips": { 13 | "apps": ["B3LX46C5HS.xyz.blueskyweb.app.AppClip"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/components/ContextMenu/index.web.tsx: -------------------------------------------------------------------------------- 1 | import {type AuxiliaryViewProps} from './types' 2 | 3 | export * from '#/components/Menu' 4 | 5 | export function Provider({children}: {children: React.ReactNode}) { 6 | return children 7 | } 8 | 9 | // native only 10 | export function AuxiliaryView({}: AuxiliaryViewProps) { 11 | return null 12 | } 13 | -------------------------------------------------------------------------------- /src/components/icons/Flag.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Flag_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4 4a2 2 0 0 1 2-2h13.131c1.598 0 2.55 1.78 1.665 3.11L18.202 9l2.594 3.89c.886 1.33-.067 3.11-1.665 3.11H6v5a1 1 0 1 1-2 0V4Zm2 10h13.131l-2.593-3.89a2 2 0 0 1 0-2.22L19.13 4H6v10Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/TextSize.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const TextSize_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M9 5a1 1 0 0 1 1-1h12a1 1 0 1 1 0 2h-5v14a1 1 0 1 1-2 0V6h-5a1 1 0 0 1-1-1Zm-3.073 7v8a1 1 0 1 0 2 0v-8H12a1 1 0 1 0 0-2H6.971a1.015 1.015 0 0 0-.089 0H2a1 1 0 1 0 0 2h3.927Z', 5 | }) 6 | -------------------------------------------------------------------------------- /modules/BlueskyClip/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "App-Icon-1024x1024@1x.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /assets/icons/flag_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pause_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /jest/dev-infra/with-test-redis-and-db.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Example usage: 4 | # ./with-test-redis-and-db.sh psql postgresql://pg:password@localhost:5433/postgres -c 'select 1;' 5 | # ./with-test-redis-and-db.sh redis-cli -h localhost -p 6380 ping 6 | 7 | dir=$(dirname $0) 8 | . ${dir}/_common.sh 9 | 10 | SERVICES="db_test redis_test" main "$@" 11 | -------------------------------------------------------------------------------- /src/components/icons/Clock.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Clock_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm8-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm1 6a1 1 0 1 0-2 0v4a1 1 0 0 0 .293.707l2.5 2.5a1 1 0 0 0 1.414-1.414L13 11.586V8Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Phone.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Phone_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M5 4a3 3 0 0 1 3-3h8a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3V4Zm3-1a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H8Zm2 2a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /__mocks__/react-native-image-crop-picker.js: -------------------------------------------------------------------------------- 1 | export const openPicker = jest 2 | .fn() 3 | .mockImplementation(() => Promise.resolve({uri: ''})) 4 | export const openCamera = jest 5 | .fn() 6 | .mockImplementation(() => Promise.resolve({uri: ''})) 7 | export const openCropper = jest 8 | .fn() 9 | .mockImplementation(() => Promise.resolve({uri: ''})) 10 | -------------------------------------------------------------------------------- /assets/icons/lock_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pin_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/MagnifyingGlass.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const MagnifyingGlass_Filled_Stroke2_Corner0_Rounded = 4 | createSinglePathSVG({ 5 | path: 'M5 11a6 6 0 1 1 12 0 6 6 0 0 1-12 0Zm6-8a8 8 0 1 0 4.906 14.32l3.387 3.387a1 1 0 0 0 1.414-1.414l-3.387-3.387A8 8 0 0 0 11 3Zm4 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z', 6 | }) 7 | -------------------------------------------------------------------------------- /src/types/bsky/profile.ts: -------------------------------------------------------------------------------- 1 | import {AppBskyActorDefs, ChatBskyActorDefs} from '@atproto/api' 2 | 3 | /** 4 | * Matches any profile view exported by our SDK 5 | */ 6 | export type AnyProfileView = 7 | | AppBskyActorDefs.ProfileViewBasic 8 | | AppBskyActorDefs.ProfileView 9 | | AppBskyActorDefs.ProfileViewDetailed 10 | | ChatBskyActorDefs.ProfileViewBasic 11 | -------------------------------------------------------------------------------- /assets/icons/clock_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/star_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /scripts/useBuildNumberEnv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | outputIos=$(eas build:version:get -p ios) 3 | outputAndroid=$(eas build:version:get -p android) 4 | BSKY_IOS_BUILD_NUMBER=${outputIos#*buildNumber - } 5 | BSKY_ANDROID_VERSION_CODE=${outputAndroid#*versionCode - } 6 | 7 | bash -c "BSKY_IOS_BUILD_NUMBER=$BSKY_IOS_BUILD_NUMBER BSKY_ANDROID_VERSION_CODE=$BSKY_ANDROID_VERSION_CODE $*" 8 | -------------------------------------------------------------------------------- /src/components/hooks/useOnKeyboard.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Keyboard} from 'react-native' 3 | 4 | export function useOnKeyboardDidShow(cb: () => unknown) { 5 | React.useEffect(() => { 6 | const subscription = Keyboard.addListener('keyboardDidShow', cb) 7 | 8 | return () => { 9 | subscription.remove() 10 | } 11 | }, [cb]) 12 | } 13 | -------------------------------------------------------------------------------- /assets/icons/leaf_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/phone_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandlerInterface.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.backgroundnotificationhandler 2 | 3 | import com.google.firebase.messaging.RemoteMessage 4 | 5 | interface BackgroundNotificationHandlerInterface { 6 | fun showMessage(remoteMessage: RemoteMessage) 7 | } 8 | -------------------------------------------------------------------------------- /src/components/icons/Growth.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Growth_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h1a8.003 8.003 0 0 1 7.75 6.006A7.985 7.985 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Leaf.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Leaf_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h1a8.003 8.003 0 0 1 7.75 6.006A7.985 7.985 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/camera_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/growth_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyweb/cmd/embedr/render.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "html/template" 5 | "io" 6 | 7 | "github.com/labstack/echo/v4" 8 | ) 9 | 10 | type Template struct { 11 | templates *template.Template 12 | } 13 | 14 | func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { 15 | return t.templates.ExecuteTemplate(w, name, data) 16 | } 17 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/index.ts: -------------------------------------------------------------------------------- 1 | import * as PlatformInfo from './src/PlatformInfo' 2 | import {AudioCategory} from './src/PlatformInfo/types' 3 | import * as Referrer from './src/Referrer' 4 | import * as SharedPrefs from './src/SharedPrefs' 5 | import VisibilityView from './src/VisibilityView' 6 | 7 | export {AudioCategory, PlatformInfo, Referrer, SharedPrefs, VisibilityView} 8 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/VisibilityView/index.tsx: -------------------------------------------------------------------------------- 1 | import {NotImplementedError} from '../NotImplemented' 2 | import {VisibilityViewProps} from './types' 3 | 4 | export async function updateActiveViewAsync() { 5 | throw new NotImplementedError() 6 | } 7 | 8 | export default function VisibilityView({children}: VisibilityViewProps) { 9 | return children 10 | } 11 | -------------------------------------------------------------------------------- /src/components/icons/PaperPlane.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const PaperPlane_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3.374 3.22a1 1 0 0 1 1.073-.114l16 8a1 1 0 0 1 0 1.788l-16 8a1 1 0 0 1-1.417-1.136L4.97 12 3.03 4.243a1 1 0 0 1 .344-1.023ZM6.781 13l-1.284 5.133L17.764 12 5.497 5.867 6.781 11H9a1 1 0 1 1 0 2H6.78Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Times.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const TimesLarge_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4.293 4.293a1 1 0 0 1 1.414 0L12 10.586l6.293-6.293a1 1 0 1 1 1.414 1.414L13.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414L12 13.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L10.586 12 4.293 5.707a1 1 0 0 1 0-1.414Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/moderation/blocked-and-muted.ts: -------------------------------------------------------------------------------- 1 | import * as bsky from '#/types/bsky' 2 | 3 | export function isBlockedOrBlocking(profile: bsky.profile.AnyProfileView) { 4 | return profile.viewer?.blockedBy || profile.viewer?.blocking 5 | } 6 | 7 | export function isMuted(profile: bsky.profile.AnyProfileView) { 8 | return profile.viewer?.muted || profile.viewer?.mutedByList 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/strings/bidi.ts: -------------------------------------------------------------------------------- 1 | const LEFT_TO_RIGHT_EMBEDDING = '\u202A' 2 | const POP_DIRECTIONAL_FORMATTING = '\u202C' 3 | 4 | /* 5 | * Force LTR directionality in a string. 6 | * https://www.unicode.org/reports/tr9/#Directional_Formatting_Characters 7 | */ 8 | export function forceLTR(str: string) { 9 | return LEFT_TO_RIGHT_EMBEDDING + str + POP_DIRECTIONAL_FORMATTING 10 | } 11 | -------------------------------------------------------------------------------- /assets/icons/heart2_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/paperPlane_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/BlueskyNSE/BlueskyNSE.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.app.bsky 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/icons/CircleInfo.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CircleInfo_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm8-1a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-4a1 1 0 0 1-1-1Zm1-3a1 1 0 1 0 2 0 1 1 0 0 0-2 0Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/VideoClip.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const VideoClip_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 011-1h16a1 1 0 011 1v16a1 1 0 01-1 1H4a1 1 0 01-1-1V4Zm2 1v2h2V5H5Zm4 0v6h6V5H9Zm8 0v2h2V5h-2Zm2 4h-2v2h2V9Zm0 4h-2v2h2V13Zm0 4h-2V19h2ZM15 19v-6H9v6h6Zm-8 0v-2H5v2h2Zm-2-4h2v-2H5v2Zm0-4h2V9H5v2Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/timesLarge_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/heart2_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/PageText.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const PageText_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M5 2a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H5Zm1 18V4h12v16H6Zm3-6a1 1 0 1 0 0 2h2a1 1 0 1 0 0-2H9Zm-1-3a1 1 0 0 1 1-1h6a1 1 0 1 1 0 2H9a1 1 0 0 1-1-1Zm1-5a1 1 0 0 0 0 2h6a1 1 0 1 0 0-2H9Z', 5 | }) 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore everything except JS-ey or CSS code. 2 | # Based on https://stackoverflow.com/a/70715829/458193 3 | * 4 | !**/*.js 5 | !**/*.jsx 6 | !**/*.ts 7 | !**/*.tsx 8 | !*/ 9 | 10 | !**/*.css 11 | 12 | # More specific ignores go below. 13 | .expo 14 | android 15 | ios 16 | src/locale/locales 17 | lib/react-compiler-runtime 18 | bskyweb/static 19 | coverage 20 | web-build 21 | -------------------------------------------------------------------------------- /assets/icons/circleInfo_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/squareArrowTopRight_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/userCircle_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/FloppyDisk.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const FloppyDisk_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h13a1 1 0 0 1 .707.293l3 3A1 1 0 0 1 21 7v13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm6 15h6v-5H9v5Zm8 0v-6a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v6H5V5h2v3a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V5.414l2 2V19h-2ZM15 5H9v2h6V5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/SquareArrowTopRight.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const SquareArrowTopRight_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M14 5a1 1 0 1 1 0-2h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V6.414l-7.293 7.293a1 1 0 0 1-1.414-1.414L17.586 5H14ZM3 6a1 1 0 0 1 1-1h5a1 1 0 0 1 0 2H5v12h12v-4a1 1 0 1 1 2 0v5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/notifications/notifications.e2e.ts: -------------------------------------------------------------------------------- 1 | export function useNotificationsRegistration() {} 2 | 3 | export function useRequestNotificationsPermission() { 4 | return async ( 5 | _context: 'StartOnboarding' | 'AfterOnboarding' | 'Login' | 'Home', 6 | ) => {} 7 | } 8 | 9 | export async function decrementBadgeCount(_by: number) {} 10 | 11 | export async function resetBadgeCount() {} 12 | -------------------------------------------------------------------------------- /assets/icons/pageText_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/Share-with-Bluesky/Share-with-Bluesky.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.app.bsky 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/icons/Filter.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Filter_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v4a1 1 0 0 1-.293.707L15 14.414V20a1 1 0 0 1-.758.97l-4 1A1 1 0 0 1 9 21v-6.586L3.293 8.707A1 1 0 0 1 3 8V4Zm2 1v2.586l5.707 5.707A1 1 0 0 1 11 14v5.72l2-.5V14a1 1 0 0 1 .293-.707L19 7.586V5H5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/floppyDisk_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/lib/hooks/useAnimatedValue.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import {Animated} from 'react-native' 3 | 4 | export function useAnimatedValue(initialValue: number) { 5 | const lazyRef = React.useRef() 6 | 7 | if (lazyRef.current === undefined) { 8 | lazyRef.current = new Animated.Value(initialValue) 9 | } 10 | 11 | return lazyRef.current as Animated.Value 12 | } 13 | -------------------------------------------------------------------------------- /src/view/com/util/fab/FAB.web.tsx: -------------------------------------------------------------------------------- 1 | import {View} from 'react-native' 2 | 3 | import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 4 | import {FABInner, FABProps} from './FABInner' 5 | 6 | export const FAB = (_opts: FABProps) => { 7 | const {isDesktop} = useWebMediaQueries() 8 | 9 | if (!isDesktop) { 10 | return 11 | } 12 | 13 | return 14 | } 15 | -------------------------------------------------------------------------------- /assets/icons/bell_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/filter_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/homeOpen_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pencil_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/play_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/circleInfo_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Download.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Download_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 3a1 1 0 0 1 1 1v8.086l1.793-1.793a1 1 0 1 1 1.414 1.414l-3.5 3.5a1 1 0 0 1-1.414 0l-3.5-3.5a1 1 0 1 1 1.414-1.414L11 12.086V4a1 1 0 0 1 1-1ZM4 14a1 1 0 0 1 1 1v4h14v-4a1 1 0 1 1 2 0v5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Window.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Window_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M6 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V6a3 3 0 0 0-3-3H6ZM5 18v-6h14v6a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1Zm0-8h14V6a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1v4Zm6-3.5a1 1 0 1 0 0 2h6a1 1 0 1 0 0-2h-6ZM7.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/bell2_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/chevronTopBottom_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/lock_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pencilLine_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/videoClip_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyogcard/src/routes/health.ts: -------------------------------------------------------------------------------- 1 | import {Express} from 'express' 2 | 3 | import {AppContext} from '../context.js' 4 | import {handler} from './util.js' 5 | 6 | export default function (ctx: AppContext, app: Express) { 7 | return app.get( 8 | '/_health', 9 | handler(async (_req, res) => { 10 | const {version} = ctx.cfg.service 11 | return res.send({version}) 12 | }), 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/components/forms/DateField/types.ts: -------------------------------------------------------------------------------- 1 | export type DateFieldRef = { 2 | focus: () => void 3 | blur: () => void 4 | } 5 | export type DateFieldProps = { 6 | value: string | Date 7 | onChangeDate: (date: string) => void 8 | label: string 9 | inputRef?: React.Ref 10 | isInvalid?: boolean 11 | testID?: string 12 | accessibilityHint?: string 13 | maximumDate?: string | Date 14 | } 15 | -------------------------------------------------------------------------------- /src/components/icons/ArrowOutOfBox.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const ArrowOutOfBox_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12.707 3.293a1 1 0 0 0-1.414 0l-4.5 4.5a1 1 0 0 0 1.414 1.414L11 6.414v8.836a1 1 0 1 0 2 0V6.414l2.793 2.793a1 1 0 1 0 1.414-1.414l-4.5-4.5ZM5 12.75a1 1 0 1 0-2 0V20a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1v-7.25a1 1 0 1 0-2 0V19H5v-6.25Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/locale/i18nProvider.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {i18n} from '@lingui/core' 3 | import {I18nProvider as DefaultI18nProvider} from '@lingui/react' 4 | 5 | import {useLocaleLanguage} from './i18n' 6 | 7 | export default function I18nProvider({children}: {children: React.ReactNode}) { 8 | useLocaleLanguage() 9 | return {children} 10 | } 11 | -------------------------------------------------------------------------------- /assets/icons/arrowOutOfBox_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowsDiagonalOut_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/bubble_stroke2_corner3_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/download_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/flipHorizontal_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/flipVertical_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.ts: -------------------------------------------------------------------------------- 1 | import {requireNativeModule} from 'expo-modules-core' 2 | 3 | import {ExpoBackgroundNotificationHandlerModule} from './ExpoBackgroundNotificationHandler.types' 4 | 5 | export const BackgroundNotificationHandler = 6 | requireNativeModule( 7 | 'ExpoBackgroundNotificationHandler', 8 | ) 9 | -------------------------------------------------------------------------------- /patches/expo-updates+0.26.10.patch.md: -------------------------------------------------------------------------------- 1 | # Expo-Updates Patch 2 | 3 | This is a small patch to convert timestamp formats that are returned from the backend. Instead of relying on the 4 | backend to return the correct format for a specific format (the format required on Android is not the same as on iOS) 5 | we can just add this conversion in. 6 | 7 | Don't remove unless we make changes on the backend to support both platforms. 8 | -------------------------------------------------------------------------------- /src/lib/broadcast/stub.ts: -------------------------------------------------------------------------------- 1 | export default class BroadcastChannel { 2 | constructor(public name: string) {} 3 | postMessage(_data: any) {} 4 | close() {} 5 | onmessage: (event: MessageEvent) => void = () => {} 6 | addEventListener(_type: string, _listener: (event: MessageEvent) => void) {} 7 | removeEventListener( 8 | _type: string, 9 | _listener: (event: MessageEvent) => void, 10 | ) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/types/bsky/starterPack.ts: -------------------------------------------------------------------------------- 1 | import {AppBskyGraphDefs} from '@atproto/api' 2 | 3 | export const isBasicView = AppBskyGraphDefs.isStarterPackViewBasic 4 | export const isView = AppBskyGraphDefs.isStarterPackView 5 | 6 | /** 7 | * Matches any starter pack view exported by our SDK 8 | */ 9 | export type AnyStarterPackView = 10 | | AppBskyGraphDefs.StarterPackViewBasic 11 | | AppBskyGraphDefs.StarterPackView 12 | -------------------------------------------------------------------------------- /assets/icons/bubble_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/bulletList_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/settingsSliderVertical_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/window_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyweb/static/robots.txt: -------------------------------------------------------------------------------- 1 | # Hello Friends! 2 | # If you are considering bulk or automated crawling, you may want to look in 3 | # to our protocol (API), including a firehose of updates. See: https://atproto.com/ 4 | 5 | # By default, may crawl anything on this domain. HTTP 429 ("backoff") status 6 | # codes are used for rate-limiting. Up to a handful concurrent requests should 7 | # be ok. 8 | User-Agent: * 9 | Allow: / 10 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/Referrer/index.ts: -------------------------------------------------------------------------------- 1 | import {NotImplementedError} from '../NotImplemented' 2 | import {GooglePlayReferrerInfo, ReferrerInfo} from './types' 3 | 4 | export function getGooglePlayReferrerInfoAsync(): Promise { 5 | throw new NotImplementedError() 6 | } 7 | 8 | export function getReferrerInfo(): ReferrerInfo | null { 9 | throw new NotImplementedError() 10 | } 11 | -------------------------------------------------------------------------------- /src/components/icons/EditBig.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const EditBig_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M17.293 2.293a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1 0 1.414l-9 9A1 1 0 0 1 12 16H9a1 1 0 0 1-1-1v-3a1 1 0 0 1 .293-.707l9-9ZM10 12.414V14h1.586l8-8L18 4.414l-8 8ZM3 4a1 1 0 0 1 1-1h7a1 1 0 1 1 0 2H5v14h14v-6a1 1 0 1 1 2 0v7a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/browser.ts: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/questions/7944460/detect-safari-browser 2 | export const isSafari = /^((?!chrome|android).)*safari/i.test( 3 | navigator.userAgent, 4 | ) 5 | export const isFirefox = /firefox|fxios/i.test(navigator.userAgent) 6 | export const isTouchDevice = window.matchMedia('(pointer: coarse)').matches 7 | export const isAndroidWeb = 8 | /android/i.test(navigator.userAgent) && isTouchDevice 9 | -------------------------------------------------------------------------------- /src/state/persisted/types.ts: -------------------------------------------------------------------------------- 1 | import type {Schema} from './schema' 2 | 3 | export type PersistedApi = { 4 | init(): Promise 5 | get(key: K): Schema[K] 6 | write(key: K, value: Schema[K]): Promise 7 | onUpdate( 8 | key: K, 9 | cb: (v: Schema[K]) => void, 10 | ): () => void 11 | clearStorage: () => Promise 12 | } 13 | -------------------------------------------------------------------------------- /assets/icons/arrowsDiagonalOut_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/Splash.android.tsx: -------------------------------------------------------------------------------- 1 | import {useEffect} from 'react' 2 | import * as SplashScreen from 'expo-splash-screen' 3 | 4 | type Props = { 5 | isReady: boolean 6 | } 7 | 8 | export function Splash({isReady, children}: React.PropsWithChildren) { 9 | useEffect(() => { 10 | if (isReady) { 11 | SplashScreen.hideAsync() 12 | } 13 | }, [isReady]) 14 | if (isReady) { 15 | return children 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/components/icons/Moon.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Moon_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12.097 2.53a1 1 0 0 1-.041 1.07 6 6 0 0 0 8.345 8.344 1 1 0 0 1 1.563.908c-.434 5.122-4.728 9.144-9.962 9.144-5.522 0-9.998-4.476-9.998-9.998 0-5.234 4.021-9.528 9.144-9.962a1 1 0 0 1 .949.494ZM9.424 4.424a7.998 7.998 0 1 0 10.152 10.152A8 8 0 0 1 9.424 4.424Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/SettingsSlider.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const SettingsSliderVertical_Stroke2_Corner0_Rounded = 4 | createSinglePathSVG({ 5 | path: 'M7 3a1 1 0 0 1 1 1v1.126a4 4 0 0 1 0 7.748V20a1 1 0 1 1-2 0v-7.126a4 4 0 0 1 0-7.748V4a1 1 0 0 1 1-1Zm10 0a1 1 0 0 1 1 1v9.126a4 4 0 1 1-2 0V4a1 1 0 0 1 1-1ZM7 7a2 2 0 1 0 0 4 2 2 0 1 0 0-4Zm10 8a2 2 0 1 0 0 4 2 2 0 1 0 0-4Z', 6 | }) 7 | -------------------------------------------------------------------------------- /assets/icons/editBig_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyweb/embedr-static/robots.txt: -------------------------------------------------------------------------------- 1 | # Hello Friends! 2 | # If you are considering bulk or automated crawling, you may want to look in 3 | # to our protocol (API), including a firehose of updates. See: https://atproto.com/ 4 | 5 | # By default, may crawl anything on this domain. HTTP 429 ("backoff") status 6 | # codes are used for rate-limiting. Up to a handful concurrent requests should 7 | # be ok. 8 | User-Agent: * 9 | Allow: / 10 | -------------------------------------------------------------------------------- /assets/icons/arrowsDiagonalIn_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowsDiagonalIn_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/moon_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/person_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskylink/src/routes/root.ts: -------------------------------------------------------------------------------- 1 | import {Express} from 'express' 2 | 3 | import {AppContext} from '../context.js' 4 | import {handler} from './util.js' 5 | 6 | export default function (ctx: AppContext, app: Express) { 7 | return app.get( 8 | '/', 9 | handler(async (_req, res) => { 10 | res.setHeader('Location', `https://${ctx.cfg.service.appHostname}`) 11 | return res.status(301).end() 12 | }), 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/components/Divider.tsx: -------------------------------------------------------------------------------- 1 | import {View} from 'react-native' 2 | 3 | import {atoms as a, flatten, useTheme, ViewStyleProp} from '#/alf' 4 | 5 | export function Divider({style}: ViewStyleProp) { 6 | const t = useTheme() 7 | 8 | return ( 9 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /src/state/queries/index.ts: -------------------------------------------------------------------------------- 1 | const SECOND = 1e3 2 | const MINUTE = SECOND * 60 3 | const HOUR = MINUTE * 60 4 | 5 | export const STALE = { 6 | SECONDS: { 7 | FIFTEEN: 15 * SECOND, 8 | THIRTY: 30 * SECOND, 9 | }, 10 | MINUTES: { 11 | ONE: MINUTE, 12 | THREE: 3 * MINUTE, 13 | FIVE: 5 * MINUTE, 14 | THIRTY: 30 * MINUTE, 15 | }, 16 | HOURS: { 17 | ONE: HOUR, 18 | }, 19 | INFINITY: Infinity, 20 | } 21 | -------------------------------------------------------------------------------- /assets/icons/circleBanSign_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/ios/ExpoScrollForwarderModule.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | public class ExpoScrollForwarderModule: Module { 4 | public func definition() -> ModuleDefinition { 5 | Name("ExpoScrollForwarder") 6 | 7 | View(ExpoScrollForwarderView.self) { 8 | Prop("scrollViewTag") { (view: ExpoScrollForwarderView, prop: Int) in 9 | view.scrollViewTag = prop 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/icons/arrowBoxLeft_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowBoxLeft_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/arrowRotateCounterClockwise_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-bluesky-gif-view/src/GifView.types.ts: -------------------------------------------------------------------------------- 1 | import {ViewProps} from 'react-native' 2 | 3 | export interface GifViewStateChangeEvent { 4 | nativeEvent: { 5 | isPlaying: boolean 6 | isLoaded: boolean 7 | } 8 | } 9 | 10 | export interface GifViewProps extends ViewProps { 11 | autoplay?: boolean 12 | source?: string 13 | placeholderSource?: string 14 | onPlayerStateChange?: (event: GifViewStateChangeEvent) => void 15 | } 16 | -------------------------------------------------------------------------------- /src/components/icons/CircleBanSign.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CircleBanSign_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 4a8 8 0 0 0-6.32 12.906L16.906 5.68A7.962 7.962 0 0 0 12 4Zm6.32 3.094L7.094 18.32A8 8 0 0 0 18.32 7.094ZM2 12C2 6.477 6.477 2 12 2a9.972 9.972 0 0 1 7.071 2.929A9.972 9.972 0 0 1 22 12c0 5.523-4.477 10-10 10a9.972 9.972 0 0 1-7.071-2.929A9.972 9.972 0 0 1 2 12Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/hooks/useAppState.ts: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from 'react' 2 | import {AppState} from 'react-native' 3 | 4 | export function useAppState() { 5 | const [state, setState] = useState(AppState.currentState) 6 | 7 | useEffect(() => { 8 | const sub = AppState.addEventListener('change', nextAppState => { 9 | setState(nextAppState) 10 | }) 11 | return () => sub.remove() 12 | }, []) 13 | 14 | return state 15 | } 16 | -------------------------------------------------------------------------------- /src/lib/type-guards.ts: -------------------------------------------------------------------------------- 1 | export function isObj(v: unknown): v is Record { 2 | return !!v && typeof v === 'object' 3 | } 4 | 5 | export function hasProp( 6 | data: object, 7 | prop: K, 8 | ): data is Record { 9 | return prop in data 10 | } 11 | 12 | export function isStrArray(v: unknown): v is string[] { 13 | return Array.isArray(v) && v.every(item => typeof item === 'string') 14 | } 15 | -------------------------------------------------------------------------------- /assets/icons/clipboard_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Clipboard.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Clipboard_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M8.17 4A3.001 3.001 0 0 1 11 2h2c1.306 0 2.418.835 2.83 2H17a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h1.17ZM8 6H7a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-1v1a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V6Zm6 0V5a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v1h4Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/FilterTimeline.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const FilterTimeline_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M7.002 5a1 1 0 0 0-2 0v11.587l-1.295-1.294a1 1 0 0 0-1.414 1.414l3.002 3a1 1 0 0 0 1.414 0l2.998-3a1 1 0 0 0-1.414-1.414l-1.291 1.292V5ZM16 16a1 1 0 1 0 0 2h4a1 1 0 1 0 0-2h-4Zm-3-4a1 1 0 0 1 1-1h6a1 1 0 1 1 0 2h-6a1 1 0 0 1-1-1Zm-1-6a1 1 0 1 0 0 2h8a1 1 0 1 0 0-2h-8Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/filterTimeline_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyogcard/src/routes/index.ts: -------------------------------------------------------------------------------- 1 | import {Express} from 'express' 2 | 3 | import {AppContext} from '../context.js' 4 | import {default as health} from './health.js' 5 | import {default as starterPack} from './starter-pack.js' 6 | 7 | export * from './util.js' 8 | 9 | export default function (ctx: AppContext, app: Express) { 10 | app = health(ctx, app) // GET /_health 11 | app = starterPack(ctx, app) // GET /start/:actor/:rkey 12 | return app 13 | } 14 | -------------------------------------------------------------------------------- /src/components/ReportDialog/types.ts: -------------------------------------------------------------------------------- 1 | import * as Dialog from '#/components/Dialog' 2 | 3 | export type ReportDialogProps = { 4 | control: Dialog.DialogOuterProps['control'] 5 | params: 6 | | { 7 | type: 'post' | 'list' | 'feedgen' | 'starterpack' | 'other' 8 | uri: string 9 | cid: string 10 | } 11 | | { 12 | type: 'account' 13 | did: string 14 | } 15 | | {type: 'convoMessage'} 16 | } 17 | -------------------------------------------------------------------------------- /src/components/dms/MessageContext.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const MessageContext = React.createContext(false) 4 | 5 | export function MessageContextProvider({ 6 | children, 7 | }: { 8 | children: React.ReactNode 9 | }) { 10 | return ( 11 | {children} 12 | ) 13 | } 14 | 15 | export function useIsWithinMessage() { 16 | return React.useContext(MessageContext) 17 | } 18 | -------------------------------------------------------------------------------- /assets/icons/personPlus_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugins/shareExtension/withAppEntitlements.js: -------------------------------------------------------------------------------- 1 | const {withEntitlementsPlist} = require('@expo/config-plugins') 2 | 3 | const withAppEntitlements = config => { 4 | // eslint-disable-next-line no-shadow 5 | return withEntitlementsPlist(config, async config => { 6 | config.modResults['com.apple.security.application-groups'] = [ 7 | `group.app.bsky`, 8 | ] 9 | return config 10 | }) 11 | } 12 | 13 | module.exports = {withAppEntitlements} 14 | -------------------------------------------------------------------------------- /src/components/icons/EnveopeOpen.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Envelope_Open_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v6.386c1.064-.002 2 .86 2 2.001V19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-6.613c0-1.142.936-2.003 2-2.001V4Zm2 6.946 6 2 6-2V4H6v6.946ZM9 8a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2h-4a1 1 0 0 1-1-1Zm2.367 6.843L4 12.387V19h16v-6.613l-7.367 2.456a2 2 0 0 1-1.265 0Z', 5 | }) 6 | -------------------------------------------------------------------------------- /plugins/notificationsExtension/withAppEntitlements.js: -------------------------------------------------------------------------------- 1 | const {withEntitlementsPlist} = require('@expo/config-plugins') 2 | 3 | const withAppEntitlements = config => { 4 | // eslint-disable-next-line no-shadow 5 | return withEntitlementsPlist(config, async config => { 6 | config.modResults['com.apple.security.application-groups'] = [ 7 | `group.app.bsky`, 8 | ] 9 | return config 10 | }) 11 | } 12 | 13 | module.exports = {withAppEntitlements} 14 | -------------------------------------------------------------------------------- /src/components/icons/ArrowRotateCounterClockwise.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded = 4 | createSinglePathSVG({ 5 | path: 'M5 3a1 1 0 0 1 1 1v1.423c.498-.46 1.02-.869 1.58-1.213C8.863 3.423 10.302 3 12.028 3a9 9 0 1 1-8.487 12 1 1 0 0 1 1.885-.667A7 7 0 1 0 12.028 5c-1.37 0-2.444.327-3.402.915-.474.29-.93.652-1.383 1.085H9a1 1 0 0 1 0 2H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Z', 6 | }) 7 | -------------------------------------------------------------------------------- /assets/icons/cc_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/envelope_open_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Plus.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const PlusLarge_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 3a1 1 0 0 1 1 1v7h7a1 1 0 1 1 0 2h-7v7a1 1 0 1 1-2 0v-7H4a1 1 0 1 1 0-2h7V4a1 1 0 0 1 1-1Z', 5 | }) 6 | 7 | export const PlusSmall_Stroke2_Corner0_Rounded = createSinglePathSVG({ 8 | path: 'M12 6a1 1 0 0 1 1 1v4h4a1 1 0 1 1 0 2h-4v4a1 1 0 1 1-2 0v-4H7a1 1 0 1 1 0-2h4V7a1 1 0 0 1 1-1Z', 9 | }) 10 | -------------------------------------------------------------------------------- /src/view/com/composer/photos/EditImageDialog.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import {ComposerImage} from '#/state/gallery' 4 | import * as Dialog from '#/components/Dialog' 5 | 6 | export type EditImageDialogProps = { 7 | control: Dialog.DialogOuterProps['control'] 8 | image: ComposerImage 9 | onChange: (next: ComposerImage) => void 10 | } 11 | 12 | export const EditImageDialog = ({}: EditImageDialogProps): React.ReactNode => { 13 | return null 14 | } 15 | -------------------------------------------------------------------------------- /src/view/com/util/LoadingScreen.tsx: -------------------------------------------------------------------------------- 1 | import {ActivityIndicator, View} from 'react-native' 2 | 3 | import {s} from '#/lib/styles' 4 | import * as Layout from '#/components/Layout' 5 | 6 | /** 7 | * @deprecated use Layout compoenents directly 8 | */ 9 | export function LoadingScreen() { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /assets/icons/bell_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/cc_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/alf/util/themeSelector.ts: -------------------------------------------------------------------------------- 1 | import {ThemeName} from '#/alf/types' 2 | 3 | export function select(name: ThemeName, options: Record) { 4 | switch (name) { 5 | case 'light': 6 | return options.light 7 | case 'dark': 8 | return options.dark || options.dim 9 | case 'dim': 10 | return options.dim || options.dark 11 | default: 12 | throw new Error(`select(theme, options) received unknown theme ${name}`) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/icons/Trending2.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Trending2_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'm18.192 5.004 1.864 5.31a1 1 0 0 0 1.887-.662L20.08 4.34c-.665-1.893-3.378-1.741-3.834.207l-3.381 14.449-2.985-9.605C9.3 7.531 6.684 7.506 6.07 9.355l-1.18 3.56-.969-2.312a1 1 0 0 0-1.844.772l.97 2.315c.715 1.71 3.159 1.613 3.741-.144l1.18-3.56 2.985 9.605c.607 1.952 3.392 1.848 3.857-.138l3.381-14.449Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Zap.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Zap_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'm9.368 4-4 8h2.944a1.5 1.5 0 0 1 1.427 1.963l-1.65 5.087L19.374 9h-3.49a1.5 1.5 0 0 1-1.287-2.272L16.234 4H9.368Zm-1.65-1.17A1.5 1.5 0 0 1 9.058 2h8.058a1.5 1.5 0 0 1 1.286 2.272L16.766 7h3.92c1.38 0 2.028 1.703.998 2.62L8.042 21.77c-1.142 1.018-2.896-.127-2.424-1.583L7.624 14H4.56a1.5 1.5 0 0 1-1.342-2.17l4.5-9Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/state/shell/post-progress.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface PostProgressState { 4 | progress: number 5 | status: 'pending' | 'success' | 'error' | 'idle' 6 | error?: string 7 | } 8 | 9 | const PostProgressContext = React.createContext({ 10 | progress: 0, 11 | status: 'idle', 12 | }) 13 | 14 | export function Provider() {} 15 | 16 | export function usePostProgress() { 17 | return React.useContext(PostProgressContext) 18 | } 19 | -------------------------------------------------------------------------------- /assets/icons/repost_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/CircleX.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CircleX_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm6.293-3.707a1 1 0 0 1 1.414 0L12 10.586l2.293-2.293a1 1 0 1 1 1.414 1.414L13.414 12l2.293 2.293a1 1 0 0 1-1.414 1.414L12 13.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L10.586 12 8.293 9.707a1 1 0 0 1 0-1.414Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/camera_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/message_stroke2_corner0_rounded_filled.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/trending2_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /patches/@lingui+core+4.14.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/@lingui/core/dist/index.mjs b/node_modules/@lingui/core/dist/index.mjs 2 | index 9759736..881f67b 100644 3 | --- a/node_modules/@lingui/core/dist/index.mjs 4 | +++ b/node_modules/@lingui/core/dist/index.mjs 5 | @@ -1,4 +1,4 @@ 6 | -import unraw from 'unraw'; 7 | +import { unraw } from 'unraw'; 8 | import { compileMessage } from '@lingui/message-utils/compileMessage'; 9 | 10 | const isString = (s) => typeof s === "string"; 11 | -------------------------------------------------------------------------------- /src/components/icons/CodeLines.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CodeLines_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M2 5a1 1 0 0 1 1-1h10a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm15 0a1 1 0 0 1 1-1h3a1 1 0 1 1 0 2h-3a1 1 0 0 1-1-1ZM2 12a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm10 0a1 1 0 0 1 1-1h8a1 1 0 1 1 0 2h-8a1 1 0 0 1-1-1ZM2 19a1 1 0 0 1 1-1h7a1 1 0 1 1 0 2H3a1 1 0 0 1-1-1Zm12 0a1 1 0 0 1 1-1h6a1 1 0 1 1 0 2h-6a1 1 0 0 1-1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/Mute.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Mute_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M20.707 3.293a1 1 0 0 1 0 1.414l-16 16a1 1 0 0 1-1.414-1.414l2.616-2.616A1.998 1.998 0 0 1 5 15V9a2 2 0 0 1 2-2h2.697l5.748-3.832A1 1 0 0 1 17 4v1.586l2.293-2.293a1 1 0 0 1 1.414 0ZM15 7.586 7.586 15H7V9h2.697a2 2 0 0 0 1.11-.336L15 5.87v1.717Zm2 3.657-2 2v4.888l-2.933-1.955-1.442 1.442 4.82 3.214A1 1 0 0 0 17 20v-8.757Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/state/queries/nuxs/definitions.ts: -------------------------------------------------------------------------------- 1 | import zod from 'zod' 2 | 3 | import {BaseNux} from '#/state/queries/nuxs/types' 4 | 5 | export enum Nux { 6 | NeueTypography = 'NeueTypography', 7 | } 8 | 9 | export const nuxNames = new Set(Object.values(Nux)) 10 | 11 | export type AppNux = BaseNux<{ 12 | id: Nux.NeueTypography 13 | data: undefined 14 | }> 15 | 16 | export const NuxSchemas: Record | undefined> = { 17 | [Nux.NeueTypography]: undefined, 18 | } 19 | -------------------------------------------------------------------------------- /assets/icons/circleX_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/closeQuote_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/mute_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/zap_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/hooks/useRefreshOnFocus.ts: -------------------------------------------------------------------------------- 1 | import {useCallback, useRef} from 'react' 2 | import {useFocusEffect} from '@react-navigation/native' 3 | 4 | export function useRefreshOnFocus(refetch: () => Promise) { 5 | const firstTimeRef = useRef(true) 6 | 7 | useFocusEffect( 8 | useCallback(() => { 9 | if (firstTimeRef.current) { 10 | firstTimeRef.current = false 11 | return 12 | } 13 | 14 | refetch() 15 | }, [refetch]), 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/components/icons/PaintRoller.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const PaintRoller_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M6 6a3 3 0 0 1 3-3h9a3 3 0 0 1 3 3v2a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3H5v3a1 1 0 0 0 1 1h7a1 1 0 0 1 1 1v2.17c1.165.412 2 1.524 2 2.83v3a1 1 0 1 1-2 0v-3a1 1 0 1 0-2 0v3a1 1 0 1 1-2 0v-3c0-1.306.835-2.418 2-2.83V14H6a3 3 0 0 1-3-3V8a2 2 0 0 1 2-2h1Zm3-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1H9Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/codeLines_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/home_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/openQuote_filled_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/paintRoller_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pin_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /scripts/setGitHubOutput.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | outputIos=$(eas build:version:get -p ios) 3 | outputAndroid=$(eas build:version:get -p android) 4 | BSKY_IOS_BUILD_NUMBER=${outputIos#*buildNumber - } 5 | BSKY_ANDROID_VERSION_CODE=${outputAndroid#*versionCode - } 6 | 7 | echo PACKAGE_VERSION="$(jq -r '.version' package.json)" > "$GITHUB_OUTPUT" 8 | echo BSKY_IOS_BUILD_NUMBER=$BSKY_IOS_BUILD_NUMBER >> "$GITHUB_OUTPUT" 9 | echo BSKY_ANDROID_VERSION_CODE=$BSKY_ANDROID_VERSION_CODE >> "$GITHUB_OUTPUT" 10 | -------------------------------------------------------------------------------- /src/screens/VideoFeed/types.ts: -------------------------------------------------------------------------------- 1 | import {AuthorFilter} from '#/state/queries/post-feed' 2 | 3 | /** 4 | * Kind of like `FeedDescriptor` but not 5 | */ 6 | export type VideoFeedSourceContext = 7 | | { 8 | type: 'feedgen' 9 | uri: string 10 | sourceInterstitial: 'discover' | 'explore' | 'none' 11 | initialPostUri?: string 12 | } 13 | | { 14 | type: 'author' 15 | did: string 16 | filter: AuthorFilter 17 | initialPostUri?: string 18 | } 19 | -------------------------------------------------------------------------------- /assets/icons/bellOff_filled_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/eye_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/listMagnifyingGlass_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/peopleRemove2_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyweb/static/.well-known/assetlinks.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "relation": ["delegate_permission/common.handle_all_urls"], 4 | "target": { 5 | "namespace": "android_app", 6 | "package_name": "xyz.blueskyweb.app", 7 | "sha256_cert_fingerprints": 8 | ["C1:4D:3C:6B:B5:D6:D9:AE:CF:C5:0B:BC:C1:9B:29:6D:D4:E6:87:46:36:D5:4C:1A:64:1C:14:08:BF:7E:F9:62", "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"] 9 | } 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /scripts/useBuildNumberEnvWithBump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | outputIos=$(eas build:version:get -p ios) 3 | outputAndroid=$(eas build:version:get -p android) 4 | currentIosVersion=${outputIos#*buildNumber - } 5 | currentAndroidVersion=${outputAndroid#*versionCode - } 6 | 7 | BSKY_IOS_BUILD_NUMBER=$((currentIosVersion+1)) 8 | BSKY_ANDROID_VERSION_CODE=$((currentAndroidVersion+1)) 9 | 10 | bash -c "BSKY_IOS_BUILD_NUMBER=$BSKY_IOS_BUILD_NUMBER BSKY_ANDROID_VERSION_CODE=$BSKY_ANDROID_VERSION_CODE $*" 11 | 12 | -------------------------------------------------------------------------------- /src/components/icons/ListMagnifyingGlass.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const ListMagnifyingGlass_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h13a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1Zm1 4a1 1 0 0 0 0 2h5a1 1 0 0 0 0-2H4Zm-1 7a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1Zm0 5a1 1 0 0 1 1-1h13a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1Zm9-8a4 4 0 1 1 7.446 2.032l.99.989a1 1 0 1 1-1.415 1.414l-.99-.989A4 4 0 0 1 12 12Zm4-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/PeopleRemove2.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const PeopleRemove2_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M10 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM5.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM16 11a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2h-5a1 1 0 0 1-1-1ZM3.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C1.917 15.521 5.242 12 10 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 17.5 21h-15a1 1 0 0 1-.996-1.094Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/canvas.ts: -------------------------------------------------------------------------------- 1 | export const getCanvas = (base64: string): Promise => { 2 | return new Promise(resolve => { 3 | const image = new Image() 4 | image.onload = () => { 5 | const canvas = document.createElement('canvas') 6 | canvas.width = image.width 7 | canvas.height = image.height 8 | 9 | const ctx = canvas.getContext('2d') 10 | ctx?.drawImage(image, 0, 0) 11 | resolve(canvas) 12 | } 13 | image.src = base64 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /src/lib/hooks/useDedupe.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const useDedupe = (timeout = 250) => { 4 | const canDo = React.useRef(true) 5 | 6 | return React.useCallback( 7 | (cb: () => unknown) => { 8 | if (canDo.current) { 9 | canDo.current = false 10 | setTimeout(() => { 11 | canDo.current = true 12 | }, timeout) 13 | cb() 14 | return true 15 | } 16 | return false 17 | }, 18 | [timeout], 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /assets/icons/codeBrackets_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/repost_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/NotImplemented.ts: -------------------------------------------------------------------------------- 1 | import {Platform} from 'react-native' 2 | 3 | export class NotImplementedError extends Error { 4 | constructor(params = {}) { 5 | if (__DEV__) { 6 | const caller = new Error().stack?.split('\n')[2] 7 | super( 8 | `Not implemented on ${Platform.OS}. Given params: ${JSON.stringify( 9 | params, 10 | )} ${caller}`, 11 | ) 12 | } else { 13 | super('Not implemented') 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/components/hooks/useInteractionState.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export function useInteractionState() { 4 | const [state, setState] = React.useState(false) 5 | 6 | const onIn = React.useCallback(() => { 7 | setState(true) 8 | }, []) 9 | const onOut = React.useCallback(() => { 10 | setState(false) 11 | }, []) 12 | 13 | return React.useMemo( 14 | () => ({ 15 | state, 16 | onIn, 17 | onOut, 18 | }), 19 | [state, onIn, onOut], 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /assets/icons/listPlus_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /bskyembed/assets/repost_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/GameController.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const GameController_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M1 8a3 3 0 0 1 3-3h16a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3V8Zm3-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1H4Zm4 2a1 1 0 0 1 1 1v1h1a1 1 0 1 1 0 2H9v1a1 1 0 1 1-2 0v-1H6a1 1 0 1 1 0-2h1v-1a1 1 0 0 1 1-1Zm5.5 4.5a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Zm3-3a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/view/com/util/images/Image.tsx: -------------------------------------------------------------------------------- 1 | import {Image, ImageProps, ImageSource} from 'expo-image' 2 | 3 | interface HighPriorityImageProps extends ImageProps { 4 | source: ImageSource 5 | } 6 | export function HighPriorityImage({source, ...props}: HighPriorityImageProps) { 7 | const updatedSource = { 8 | uri: typeof source === 'object' && source ? source.uri : '', 9 | } satisfies ImageSource 10 | return ( 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /__tests__/lib/link-meta.test.ts: -------------------------------------------------------------------------------- 1 | import {LikelyType, getLikelyType} from '../../src/lib/link-meta/link-meta' 2 | 3 | describe('getLikelyType', () => { 4 | it('correctly handles non-parsed url', async () => { 5 | const output = await getLikelyType('https://example.com') 6 | expect(output).toEqual(LikelyType.HTML) 7 | }) 8 | 9 | it('handles non-string urls without crashing', async () => { 10 | const output = await getLikelyType('123') 11 | expect(output).toEqual(LikelyType.Other) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /assets/icons/gameController_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/trash_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/screens/Login/ScreenTransition.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {StyleProp, ViewStyle} from 'react-native' 3 | import Animated, {FadeInRight, FadeOutLeft} from 'react-native-reanimated' 4 | 5 | export function ScreenTransition({ 6 | style, 7 | children, 8 | }: { 9 | style?: StyleProp 10 | children: React.ReactNode 11 | }) { 12 | return ( 13 | 14 | {children} 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/state/session/agent-config.ts: -------------------------------------------------------------------------------- 1 | import AsyncStorage from '@react-native-async-storage/async-storage' 2 | 3 | const PREFIX = 'agent-labelers' 4 | 5 | export async function saveLabelers(did: string, value: string[]) { 6 | await AsyncStorage.setItem(`${PREFIX}:${did}`, JSON.stringify(value)) 7 | } 8 | 9 | export async function readLabelers(did: string): Promise { 10 | const rawData = await AsyncStorage.getItem(`${PREFIX}:${did}`) 11 | return rawData ? JSON.parse(rawData) : undefined 12 | } 13 | -------------------------------------------------------------------------------- /src/storage/schema.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Device data that's specific to the device and does not vary based account 3 | */ 4 | export type Device = { 5 | fontScale: '-2' | '-1' | '0' | '1' | '2' 6 | fontFamily: 'system' | 'theme' 7 | lastNuxDialog: string | undefined 8 | geolocation?: { 9 | countryCode: string | undefined 10 | } 11 | trendingBetaEnabled: boolean 12 | devMode: boolean 13 | } 14 | 15 | export type Account = { 16 | searchTermHistory?: string[] 17 | searchAccountHistory?: string[] 18 | } 19 | -------------------------------------------------------------------------------- /__e2e__/flows/post-report-flow.yml: -------------------------------------------------------------------------------- 1 | appId: xyz.blueskyweb.app 2 | --- 3 | - runScript: 4 | file: ../setupServer.js 5 | env: 6 | SERVER_PATH: "?users&follows&posts" 7 | - runFlow: 8 | file: ../setupApp.yml 9 | - tapOn: 10 | id: "e2eSignInAlice" 11 | 12 | - tapOn: 13 | id: "postDropdownBtn" 14 | index: 0 15 | - tapOn: 16 | id: "postDropdownReportBtn" 17 | - tapOn: "Create report for Misleading Post" 18 | - tapOn: "Send report to Dev-env Moderation" 19 | - tapOn: 20 | point: "50%,90%" 21 | -------------------------------------------------------------------------------- /assets/icons/emojiArc_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/hashtag_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/macintosh_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Macintosh.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Macintosh_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M4 5a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v11c0 .889-.386 1.687-1 2.236V20a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-1.764c-.614-.55-1-1.348-1-2.236V5Zm3 14v1h10v-1H7ZM7 4a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7Zm0 2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V6Zm2 1v4h6V7H9Zm4 8a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/bell2_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/pencilLine_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugins/withAndroidManifestPlugin.js: -------------------------------------------------------------------------------- 1 | const {withAndroidManifest} = require('expo/config-plugins') 2 | 3 | module.exports = function withAndroidManifestPlugin(appConfig) { 4 | return withAndroidManifest(appConfig, function (decoratedAppConfig) { 5 | try { 6 | decoratedAppConfig.modResults.manifest.application[0].$[ 7 | 'android:largeHeap' 8 | ] = 'true' 9 | } catch (e) { 10 | console.error(`withAndroidManifestPlugin failed`, e) 11 | } 12 | return decoratedAppConfig 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/components/icons/Warning.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Warning_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M11.14 4.494a.995.995 0 0 1 1.72 0l7.001 12.008a.996.996 0 0 1-.86 1.498H4.999a.996.996 0 0 1-.86-1.498L11.14 4.494Zm3.447-1.007c-1.155-1.983-4.019-1.983-5.174 0L2.41 15.494C1.247 17.491 2.686 20 4.998 20h14.004c2.312 0 3.751-2.509 2.587-4.506L14.587 3.487ZM13 9.019a1 1 0 1 0-2 0v2.994a1 1 0 1 0 2 0V9.02Zm-1 4.731a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/async/cancelable.ts: -------------------------------------------------------------------------------- 1 | export function cancelable( 2 | f: (args: A) => Promise, 3 | signal: AbortSignal, 4 | ) { 5 | return (args: A) => { 6 | return new Promise((resolve, reject) => { 7 | signal.addEventListener('abort', () => { 8 | reject(new AbortError()) 9 | }) 10 | f(args).then(resolve, reject) 11 | }) 12 | } 13 | } 14 | 15 | export class AbortError extends Error { 16 | constructor() { 17 | super('Aborted') 18 | this.name = 'AbortError' 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /assets/icons/news2_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/Image.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const Image_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm2 1v7.213l1.246-.932.044-.03a3 3 0 0 1 3.863.454c1.468 1.58 2.941 2.749 4.847 2.749 1.703 0 2.855-.555 4-1.618V5H5Zm14 10.357c-1.112.697-2.386 1.097-4 1.097-2.81 0-4.796-1.755-6.313-3.388a1 1 0 0 0-1.269-.164L5 14.712V19h14v-3.643ZM15 8a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm-3 1a3 3 0 1 1 6 0 3 3 0 0 1-6 0Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/strings/email.ts: -------------------------------------------------------------------------------- 1 | import type tldts from 'tldts' 2 | 3 | const COMMON_ERROR_PATTERN = 4 | /([a-zA-Z0-9._%+-]+)@(gnail\.(co|com)|gmaill\.(co|com)|gmai\.(co|com)|gmail\.co|gmal\.(co|com)|iclod\.(co|com)|icloud\.co|outllok\.(co|com)|outlok\.(co|com)|outlook\.co|yaoo\.(co|com)|yaho\.(co|com)|yahoo\.co|yahooo\.(co|com))$/ 5 | 6 | export function isEmailMaybeInvalid(email: string, dynamicTldts: typeof tldts) { 7 | const isIcann = dynamicTldts.parse(email).isIcann 8 | return !isIcann || COMMON_ERROR_PATTERN.test(email) 9 | } 10 | -------------------------------------------------------------------------------- /assets/icons/personPlus_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/warning_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-receive-android-intents/README.md: -------------------------------------------------------------------------------- 1 | # Expo Receive Android Intents 2 | 3 | This module handles incoming intents on Android. Handled intents are `text/plain` and `image/*` (single or multiple). 4 | The module handles saving images to the app's filesystem for access within the app, limiting the selection of images 5 | to a max of four, and handling intent types. No JS code is required for this module, and it is no-op on non-android 6 | platforms. 7 | 8 | No installation is required. Gradle will automatically add this module on build. 9 | -------------------------------------------------------------------------------- /src/components/Dialog/utils.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import {DialogControlProps} from '#/components/Dialog/types' 4 | 5 | export function useAutoOpen(control: DialogControlProps, showTimeout?: number) { 6 | React.useEffect(() => { 7 | if (showTimeout) { 8 | const timeout = setTimeout(() => { 9 | control.open() 10 | }, showTimeout) 11 | return () => { 12 | clearTimeout(timeout) 13 | } 14 | } else { 15 | control.open() 16 | } 17 | }, [control, showTimeout]) 18 | } 19 | -------------------------------------------------------------------------------- /src/components/icons/News2.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const News2_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M1 5a1 1 0 0 1 1-1h7a3.99 3.99 0 0 1 3 1.354A3.99 3.99 0 0 1 15 4h7a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-6.723c-.52 0-1 .125-1.4.372-.421.26-.761.633-.983 1.075a1 1 0 0 1-1.788 0 2.664 2.664 0 0 0-.983-1.075c-.4-.247-.88-.372-1.4-.372H2a1 1 0 0 1-1-1V5Zm10 3a2 2 0 0 0-2-2H3v12h5.723c.776 0 1.564.173 2.277.569V8Zm2 10.569V8a2 2 0 0 1 2-2h6v12h-5.723c-.776 0-1.564.173-2.277.569Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/media/video/errors.ts: -------------------------------------------------------------------------------- 1 | export class VideoTooLargeError extends Error { 2 | constructor() { 3 | super('Videos cannot be larger than 100 MB') 4 | this.name = 'VideoTooLargeError' 5 | } 6 | } 7 | 8 | export class ServerError extends Error { 9 | constructor(message: string) { 10 | super(message) 11 | this.name = 'ServerError' 12 | } 13 | } 14 | 15 | export class UploadLimitError extends Error { 16 | constructor(message: string) { 17 | super(message) 18 | this.name = 'UploadLimitError' 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /assets/icons/circleQuestion_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-bluesky-swiss-army/src/Referrer/index.android.ts: -------------------------------------------------------------------------------- 1 | import {requireNativeModule} from 'expo' 2 | 3 | import {GooglePlayReferrerInfo, ReferrerInfo} from './types' 4 | 5 | export const NativeModule = requireNativeModule('ExpoBlueskyReferrer') 6 | 7 | export function getGooglePlayReferrerInfoAsync(): Promise { 8 | return NativeModule.getGooglePlayReferrerInfoAsync() 9 | } 10 | 11 | export function getReferrerInfo(): Promise { 12 | return NativeModule.getReferrerInfo() 13 | } 14 | -------------------------------------------------------------------------------- /src/components/icons/CalendarDays.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CalendarDays_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4 3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Zm1 16V9h14v10H5ZM5 7h14V5H5v2Zm3 10.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM17.25 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM12 13.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM9.25 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM12 17.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "module": "esnext", 6 | "types": ["node", "jest"], 7 | "paths": { 8 | "#/*": ["./src/*"], 9 | "lib/*": ["./src/lib/*"], 10 | "platform/*": ["./src/platform/*"], 11 | "state/*": ["./src/state/*"], 12 | "view/*": ["./src/view/*"], 13 | "crypto": ["./src/platform/crypto.ts"] 14 | } 15 | }, 16 | "exclude": ["bskyweb", "bskyembed", "web-build"] 17 | } 18 | -------------------------------------------------------------------------------- /assets/icons/image_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/repost_stroke2_corner3_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/BubbleInfo.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const BubbleInfo_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M6.002 5h12a1 1 0 0 1 1 1v10.036a1 1 0 0 1-1 1h-2.626a2 2 0 0 0-1.276.46l-2.098 1.738-2.065-1.731a2 2 0 0 0-1.285-.467h-2.65a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Zm12-2h-12a3 3 0 0 0-3 3v10.036a3 3 0 0 0 3 3h2.65l2.704 2.266a1 1 0 0 0 1.28.004l2.74-2.27h2.626a3 3 0 0 0 3-3V6a3 3 0 0 0-3-3ZM13 11.75a1 1 0 1 0-2 0v2a1 1 0 1 0 2 0v-2ZM12 10a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /assets/icons/calendarDays_stroke2_corner0_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/bubbleInfo_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/bubbles_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/eye_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.ios.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import {requireNativeViewManager} from 'expo-modules-core' 3 | 4 | import {ExpoScrollForwarderViewProps} from './ExpoScrollForwarder.types' 5 | 6 | const NativeView: React.ComponentType = 7 | requireNativeViewManager('ExpoScrollForwarder') 8 | 9 | export function ExpoScrollForwarderView({ 10 | children, 11 | ...rest 12 | }: ExpoScrollForwarderViewProps) { 13 | return {children} 14 | } 15 | -------------------------------------------------------------------------------- /src/logger/logDump.ts: -------------------------------------------------------------------------------- 1 | import type {LogContext, LogLevel, Metadata} from '#/logger/types' 2 | 3 | export type ConsoleTransportEntry = { 4 | id: string 5 | timestamp: number 6 | level: LogLevel 7 | context: LogContext | undefined 8 | message: string | Error 9 | metadata: Metadata 10 | } 11 | 12 | let entries: ConsoleTransportEntry[] = [] 13 | 14 | export function add(entry: ConsoleTransportEntry) { 15 | entries.unshift(entry) 16 | entries = entries.slice(0, 500) 17 | } 18 | 19 | export function getEntries() { 20 | return entries 21 | } 22 | -------------------------------------------------------------------------------- /assets/icons/trash_stroke2_corner2_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/icons/CircleQuestion.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const CircleQuestion_Stroke2_Corner2_Rounded = createSinglePathSVG({ 4 | path: 'M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Z M12 9a1 1 0 0 0-.879.522 1 1 0 0 1-1.754-.96A3 3 0 0 1 12 7c1.515 0 2.567 1.006 2.866 2.189.302 1.189-.156 2.574-1.524 3.258A.62.62 0 0 0 13 13a1 1 0 1 1-2 0c0-.992.56-1.898 1.447-2.342.455-.227.572-.618.48-.978C12.836 9.314 12.529 9 12 9Z M13 16a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/icons/StreamingLive.tsx: -------------------------------------------------------------------------------- 1 | import {createSinglePathSVG} from './TEMPLATE' 2 | 3 | export const StreamingLive_Stroke2_Corner0_Rounded = createSinglePathSVG({ 4 | path: 'M4 4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H4Zm8 12.5c1.253 0 2.197.609 2.674 1.5H9.326c.477-.891 1.42-1.5 2.674-1.5Zm0-2c2.404 0 4.235 1.475 4.822 3.5H20V6H4v12h3.178c.587-2.025 2.418-3.5 4.822-3.5Zm-1.25-3.75a1.25 1.25 0 1 1 2.5 0 1.25 1.25 0 0 1-2.5 0ZM12 7.5a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5Zm5.75 2a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z', 5 | }) 6 | -------------------------------------------------------------------------------- /src/lib/hooks/useBottomBarOffset.ts: -------------------------------------------------------------------------------- 1 | import {useSafeAreaInsets} from 'react-native-safe-area-context' 2 | 3 | import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 4 | import {clamp} from '#/lib/numbers' 5 | import {isWeb} from '#/platform/detection' 6 | 7 | export function useBottomBarOffset(modifier: number = 0) { 8 | const {isTabletOrDesktop} = useWebMediaQueries() 9 | const {bottom: bottomInset} = useSafeAreaInsets() 10 | return ( 11 | (isWeb && isTabletOrDesktop ? 0 : clamp(60 + bottomInset, 60, 75)) + 12 | modifier 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/view/shell/BlockDrawerGesture.tsx: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react' 2 | import {DrawerGestureContext} from 'react-native-drawer-layout' 3 | import {Gesture, GestureDetector} from 'react-native-gesture-handler' 4 | 5 | export function BlockDrawerGesture({children}: {children: React.ReactNode}) { 6 | const drawerGesture = useContext(DrawerGestureContext) ?? Gesture.Native() // noop for web 7 | const scrollGesture = Gesture.Native().blocksExternalGesture(drawerGesture) 8 | return {children} 9 | } 10 | --------------------------------------------------------------------------------