Bluesky Social App

repository·main·Indexed 12 days ago

https://github.com/bluesky-social/social-app

A decentralized social media client built with React Native and TypeScript, powered by the AT Protocol (atproto). The repository includes the main mobile application, the bskyweb package with a Golang daemon, bskyembed for snippet testing, and BlueskyClip for iOS App Clip starter pack integration.

Tokens
50.7K
Snippets
144
Records
243
Agent score
92%

What's inside Bluesky

  1. Overview of Expo Receive Android Intents

    main

    The expo-receive-android-intents module is an Expo module designed for Android that intercepts incoming Android share intents (e.g., when a user shares content from another app to Bluesky) and converts them into deep links. This allows the app to automatically open the composer with pre-populated text, images, or videos.

    Supported Content Types:

    • Text sharing: Plain text for composing a post.
    • Image sharing: Single or multiple images (up to 4).
    • Video sharing: A single video.

    Platform Support:

    • Android: Fully supported.
    • iOS/Web: No-op (these platforms handle sharing differently).
  2. Licensing for UI glyphs in assets/icons

    main

    The SVG files located at the top level of the assets/icons/ directory are part of the Central icon system by Iconists.

    Important Licensing Restrictions:

    • These icons are not covered by the repository's MIT license.
    • The license held by Bluesky Social PBC is for their own use only and does not extend to you.
    • To use these specific icons in your own projects, you must purchase a license directly from iconists.co.

    Note that this restriction applies only to the top-level SVG files in this directory. Other assets in subdirectories or specific files have different licenses (see the ASSETS.md file for a full breakdown).

  3. License and usage for Inter font subsets

    main

    The fonts provided in this directory are subsets of the Inter font by Rasmus Andersson, used specifically by the OG card rendering service.

    Licensing

    • License Type: SIL Open Font License, Version 1.1 (OFL).
    • Redistribution: You may redistribute these files.
    • Requirement: The full license text located at assets/fonts/inter/OFL.txt must travel with these files.

    Important Restriction

    Under the OFL 1.1 Reserved Font Name provision: If you modify or subset the font further, you may not distribute the resulting font under the name "Inter."

  4. Use the Application Layout Framework (ALF) for UI primitives

    main

    The Application Layout Framework (ALF) provides a set of UI primitives and components for building layouts. It uses a naming convention similar to Tailwind CSS, but uses underscores (_) instead of hyphens (-) to allow for easier object property access in JavaScript/TypeScript.

    Naming Conventions

    • General Styles: Follow Tailwind patterns (e.g., flex_row).
    • Spacing: Uses "t-shirt" sizes: xxs, xs, sm, md, lg, xl, and xxl.
    • Text Size: Uses "t-shirt" sizes: xxs, xs, sm, md, lg, xl, and xxl to match the application's type scale.
    • Line Height: Text size atoms automatically apply a 1:1 line-height ratio. Specific overrides like tight and normal are also available.
  5. What is BlueskyClip and how does it work?

    main

    BlueskyClip is an iOS App Clip implementation designed for Bluesky starter packs. It provides a lightweight, on-demand experience that allows users to preview and join starter packs without installing the full Bluesky app.

    Core Workflow

    1. Trigger: A user taps a starter pack link (e.g., bsky.app/start/... or go.bsky.app/...).
    2. App Clip Launch: iOS presents the BlueskyClip App Clip.
    3. Web Interaction: The App Clip loads the starter pack web page in a WKWebView with the ?clip=true parameter. The web app communicates with the native layer via postMessage.
    4. Actions: The native ViewController handles two primary actions from the web layer:
      • present: Displays the App Store overlay using SKOverlay.
      • store: Saves the starter pack URI to shared UserDefaults.
    5. Handover: When the user installs the main app, it reads the starterPackUri from the shared App Group and triggers the onboarding flow.
    User taps starter pack link
            ↓
    iOS presents BlueskyClip App Clip
            ↓
    WKWebView loads bsky.app with ?clip=true parameter
            ↓
    Web app detects clip mode and sends actions via postMessage
            ↓
    ViewController receives messages and:
      - Presents App Store overlay (action: "present")
      - Stores starter pack URI in shared UserDefaults (action: "store")
            ↓
    User downloads main app
            ↓
    Main app reads starterPackUri from shared UserDefaults
            ↓
    Main app displays starter pack onboarding flow
  6. What is BlueskyNSE and how does it work?

    main

    BlueskyNSE is an iOS Notification Service Extension (NSE) that intercepts and processes push notifications before they are displayed to the user. It runs in a separate process from the main app and has a strict execution limit of approximately 30 seconds.

    Core Functions

    • Badge Count Management: Automatically increments and applies badge counts for non-chat notifications.
    • Custom Notification Sounds: Applies specific sounds (like a custom DM sound) based on user preferences.
    • Customization: Enables notification modification without requiring the main app to be active in the background.

    Architecture & Data Sharing

    To communicate with the main app, the extension uses an App Group (group.app.bsky) to access shared UserDefaults. To prevent race conditions when multiple notifications arrive simultaneously, it uses a dedicated serial DispatchQueue named NSEPrefsQueue for thread-safe access to shared preferences.

  7. Configure iOS NotificationSettings

    main

    On iOS, NotificationSettings is a pure native side effect. When push permissions are requested with provideAppNotificationSettings: true, the module adds an in-app notification settings button to the system Settings screen for Bluesky.

    Tapping this button in the system settings launches the app and triggers a deep link (bluesky://settings/notifications) which the app routes to the notification settings screen.

    Note: This module has no JavaScript surface; it operates entirely on the native side.

  8. Understand licensing for third-party service icons

    main

    The icons located in assets/icons/community/ are trademarks belonging to third-party services (such as Leaflet, Offprint, pckt, Standard.site, and Germ Network) used to identify those services within the Bluesky UI.

    Important Licensing Notes:

    • These icons are not Bluesky trademarks.
    • They are not covered by the repository's MIT license.
    • If you fork this repository and intend to use these icons, you must do so on a nominative-use basis or obtain direct permission from the respective mark owners.
    • For a comprehensive overview of all asset licensing, refer to the ASSETS.md file in the repository root.
  9. How content height detection works

    main

    The module performs native content height detection to avoid JavaScript bridge round-trips, which prevents layout jank when content changes (e.g., keyboard appearance or dynamic loading).

    • iOS: Uses KVO (Key-Value Observing) on the content view's bounds property.
    • Android: Uses OnLayoutChangeListener on child views to catch React Native's direct layout() calls.
  10. Handle translation states with translationState

    main

    When using useTranslate, you should handle the translationState.status to provide a proper user experience. The status can be one of the following:

    • idle: The default state. Typically, you should render a UI element (like a 'Translate' link) that calls the translate method.
    • loading: Translation is currently in progress on-device. Render a loading indicator.
    • success: Translation was successful. Render translationState.translatedText and provide a way to call clearTranslation to revert to the original text.
    • error: Translation failed. You can render translationState.message and optionally provide a fallback to an external service like useGoogleTranslate.
    switch (translationState.status) {
      case 'idle':
        // Render a link that calls `translate`.
        break;
      case 'loading':
        // Render a loading spinner.
        break;
      case 'success':
        // Render `translationState.translatedText` and a link that calls `clearTranslation`.
        break;
      case 'error':
        // Render `translationState.message` and a fallback link.
        break;
    }
  11. Understand OTA Deployment types

    main

    Bluesky uses Over-the-Air (OTA) deployments to update the application without requiring a full app store release. There are two types:

    1. Automatic internal OTAs: Triggered automatically on all merges into main. These deploy to TestFlight (iOS) or APK installs (Android). If native changes are detected via fingerprint diffing, a new client build is automatically triggered and delivered via TestFlight or Slack.
    2. Production OTAs: These can only update the JavaScript bundle. Any changes to native modules require a full release cycle through the app stores.
  12. How BlueskyClip communicates with the Web layer

    main

    The App Clip uses a WKScriptMessageHandler to listen for messages on the onMessage channel from the WKWebView. The web application must send JSON messages with an action key to trigger native behavior.

    Supported Actions

    • present: Triggers the App Store overlay (SKOverlay) to encourage the user to download the full app.
    • store: Instructs the native layer to write data to the shared UserDefaults suite.

    Data Sharing Mechanism

    Data is shared between the App Clip and the main app using the iOS App Group suite group.app.bsky. The primary key used for transferring the starter pack context is starterPackUri.