# FORK_DIVERGENCE

This document tracks the functional and behavioral differences between this forked repository and its upstream baseline. Each entry represents a deliberate divergence introduced to meet the specific needs of this fork.

---

### **D-0004: Legal information screen opens links in-app and adds Acknowledgement row**

- **Upstream baseline commit**: `e0ca2acc43649d4c80194d84d2179a7a9310d7eb`
- **Fork commits**: `df66185dd38ddd47a93cfd505d8210651553a072`, `bb5a6eed7e5f374eab349664f5e41b750340378c`
- **Type**: `Behavioral`
- **Date**: `2026-05-04`

#### **Description**

The Legal Information screen (About page in Settings) was modified in two related steps. First, all three legal links (Copyright, Acceptable Use Policy, Privacy Policy) were changed to open inside the app via a `WKWebView` sheet rather than delegating to the system browser via `openURL`. Second, an "Acknowledgement" row was added that links to a generated SBOM (Software Bill of Materials) JSON artifact hosted on `git.postnumber.com`, with the URL constructed dynamically from the current app version string.

#### **Upstream vs. Fork Behavior**

| Area | Upstream (Element X) | Fork (Letro) |
|---|---|---|
| Legal links (Copyright, AUP, Privacy) | Opened in external browser via `openURL` environment action | Opened in an in-app `WKWebView` sheet with a Done toolbar button |
| Acknowledgement row | Not present | Present; links to `https://git.postnumber.com/letro/letro-authentication-service/releases/download/letro-v<version>/sbom.json` |

#### **Files Modified**

- `ElementX/Sources/Screens/Settings/LegalInformationScreen/View/LegalInformationScreen.swift`

#### **Impact & Risk**

- **Impact**: Legal URLs now load inside the app, keeping users within the Letro experience. The new Acknowledgement row introduces a runtime dependency on `InfoPlistReader.main.bundleShortVersionString` and an external SBOM URL that must remain reachable for each release.
- **Risk Level**: `LOW`. Changes are self-contained to one screen. The external SBOM URL could fail silently if not published with each release.

#### **AGPL Relevance**

Not Applicable

---

### **D-0003: Push gateway URL corrected to dedicated Sygnal instance**

- **Upstream baseline commit**: `e0ca2acc43649d4c80194d84d2179a7a9310d7eb`
- **Fork commit**: `4ec100c6aa27b6f0fb1af470f364907f7b23e3b9`
- **Type**: `Behavioral`
- **Date**: `2026-05-02`

#### **Description**

The `pushGatewayBaseURL` introduced in D-0002 was set to `https://letro.com`, which was incorrect. This commit corrects it to `https://sygnal.ess.postnumber.com`, the actual dedicated Sygnal push gateway instance used by Letro.

#### **Upstream vs. Fork Behavior**

| Area | Upstream (Element X) | Fork (Letro) |
|---|---|---|
| `pushGatewayBaseURL` | `https://matrix.org` (Element's gateway) | `https://sygnal.ess.postnumber.com` (Letro's dedicated Sygnal instance) |

#### **Files Modified**

- `ElementX/Sources/Application/Settings/AppSettings.swift`

#### **Impact & Risk**

- **Impact**: Push notifications are routed to the correct Sygnal server. Without this fix, push delivery via the D-0002 value (`letro.com`) would fail.
- **Risk Level**: `LOW`. Single constant change; no structural or logic modifications.

#### **AGPL Relevance**

Not Applicable

---

### **D-0002: Letro colour palette, gradient buttons, URL corrections, and live-location permission**

- **Upstream baseline commit**: `e0ca2acc43649d4c80194d84d2179a7a9310d7eb`
- **Fork commit (merge)**: `bbdee132f18c9bfe90f448aa1f3956ddd79df39b` (PR #4 — `p-num/letroMain`)
- **Type**: `Behavioral`
- **Date**: `2026-04-16`

#### **Description**

Follow-up polish to the D-0001 rebrand: expands Letro's colour tokens and applies them more broadly, replaces flat primary buttons with a gradient, corrects remaining `element.io`/`matrix.org` URLs to `letro.com`, adds the background-location usage description required for live-location sharing, and refines localisation strings.

#### **Upstream vs. Fork Behavior**

| Area | Upstream (Element X) | Fork (Letro) |
|---|---|---|
| Primary button background | Flat fill using `bgActionPrimaryRest` token | Linear gradient (`letroGradient1 → letroGradient5`) via custom `makePrimaryBackground` in `CompoundButtonStyle` |
| Compound colour overrides | Not overridden | Extended: `gradientAction` stops, `bgActionPrimaryRest/Pressed/Disabled`, `textActionPrimary` all mapped to Letro gradient palette |
| `letroPrimary` colour | `#C20000` (D-0001) | `#F32D1B`; `letroSecondary` (`#F9BC15`) and five gradient steps (`#CB2000`–`#F7B000`) added |
| App URLs | Leftover `element.io`/`matrix.org` references | `elementWebHosts`, `accountProvisioningHost`, `pushGatewayBaseURL`, `analyticsTermsURL`, `bugReportApplicationID` corrected to `letro.com`/`letro` |
| App Store link | Element Pro app | Letro Pro app (`id6758909629`) |
| Live-location permission | `NSLocationWhenInUseUsageDescription` only | `NSLocationAlwaysAndWhenInUseUsageDescription` added for background live-location |

#### **Files Modified**

- `ElementX/Sources/Application/Settings/AppSettings.swift`
- `ElementX/Sources/Letro/Extensions/CompoundExtensions.swift`
- `ElementX/Sources/Letro/Extensions/SwiftUIExtensions.swift`
- `ElementX/SupportingFiles/Info.plist`
- `ElementX/SupportingFiles/target.yml`
- `ElementX/Resources/Localizations/en.lproj/Letro.strings`
- `ElementX/Resources/Localizations/en.lproj/Letro.stringsdict`
- `compound-ios/Sources/Compound/BaseStyles/CompoundButtonStyle.swift`

#### **Impact & Risk**

- **Impact**: Visual impact on all primary action buttons and gradient surfaces. URL changes affect bug reporting, analytics, web-link handling, and push gateway routing. Background-location permission is required for live-location feature to work correctly on iOS.
- **Risk Level**: `MEDIUM`. Colour and URL changes are self-contained; gradient button logic modifies a shared Compound component and must be retested on iOS 26.

#### **AGPL Relevance**

Not Applicable

---

### **D-0001: Letro rebranding — identity, UI, configuration, and behaviour customisations**

- **Upstream baseline commit**: `0fc0e68346f90488e4af21fd5528b2e978aa3247`
- **Fork commit (merge)**: `e0ca2acc43649d4c80194d84d2179a7a9310d7eb` (PR #1 — `p-num/letroMain`)
- **Type**: `Behavioral`
- **Date**: `2026-04-10`

#### **Description**

A comprehensive rebrand and product customisation of Element X iOS into "Letro". The changes span the app's identity (name, bundle ID, icons), its visual design (colours, shapes, custom assets), several screens (authentication, home, spaces, settings), and supporting infrastructure (string-override mechanism, SwiftGen template, entitlements).

#### **Upstream vs. Fork Behavior**

| Area | Upstream (Element X) | Fork (Letro) |
|---|---|---|
| App identity | Bundle ID `io.element.elementx`, display name "Element X", dev team `7J4U792NQT` | Bundle ID `com.letro.cloudclient`, display name "Letro", dev team `44TCX5L4G2` |
| Default Matrix server | `matrix.org` | `ess.postnumber.com` |
| Colour theme | System (light/dark) | Forced light theme; Compound gradient/accent tokens overridden with orange palette |
| Avatar shape | Circular throughout | Rounded rectangle throughout |
| Authentication screen | Element-branded scrollable layout with logo and sign-in buttons | Custom background image, logo type, "Get Started" → bottom-sheet flow showing sign-in buttons; hardcoded non-localised promo text |
| String localisation | Standard `Localizable.strings` lookup | Additional `Letro.strings`/`Letro.stringsdict` override table checked first, allowing any string to be shadowed without editing upstream files |
| Icons (tab bar / new button) | Compound icon set | Custom SVGs (`letro-icon-chat`, `letro-icon-space`, `letro-icon-new`); `CompoundIcon` patched with static override registry |
| Tab bar label colours | Default Compound accent | Custom `letroGray` (normal) / `letroPrimary` red (selected) |
| Settings screen | Shows "Report a problem" and "Analytics" rows | Both rows commented out / hidden |
| Onboarding analytics prompt | Shown when analytics consent is pending | Always skipped (`requiresAnalyticsSetup` hardcoded to `false`) |
| New-chat / new-space toolbar button | `CompoundIcon(\.plus)` with `.super` style | Custom `letro-icon-new` image; iOS 26 `sharedBackgroundVisibility` hidden |
| App URLs | All point to `element.io` | All point to `letro.com` (website, copyright, privacy, OIDC redirect, etc.) |
| Push (NSE) entitlement | Present | Temporarily removed to allow TestFlight submission |
| App version | `26.04.1` / build `1` | `1.0.3` / build `3` |

#### **Files Modified**

- `app.yml`
- `project.yml`
- `ElementX/SupportingFiles/target.yml`
- `ElementX/SupportingFiles/ElementX.entitlements`
- `NSE/SupportingFiles/NSE.entitlements`
- `ElementX/Sources/Application/Application.swift`
- `ElementX/Sources/Application/Navigation/NavigationTabCoordinator.swift`
- `ElementX/Sources/Application/Settings/AppSettings.swift`
- `ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift`
- `ElementX/Sources/Generated/Assets.swift`
- `ElementX/Sources/Generated/Strings.swift`
- `ElementX/Sources/Letro/Extensions/CompoundExtensions.swift` *(new)*
- `ElementX/Sources/Letro/Extensions/SwiftUIExtensions.swift` *(new)*
- `ElementX/Sources/Other/Avatars.swift`
- `ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift`
- `ElementX/Sources/Other/SwiftUI/Views/TombstonedAvatarImage.swift`
- `ElementX/Sources/Screens/Authentication/StartScreen/View/AuthenticationStartScreen.swift`
- `ElementX/Sources/Screens/HomeScreen/View/Filters/RoomListFilterView.swift`
- `ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift`
- `ElementX/Sources/Screens/RoomDetailsEditScreen/View/RoomDetailsEditScreen.swift`
- `ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift`
- `ElementX/Sources/Screens/Spaces/SpacesScreen/View/SpacesScreen.swift`
- `ElementX/Resources/Localizations/en.lproj/Letro.strings` *(new)*
- `ElementX/Resources/Localizations/en.lproj/Letro.stringsdict` *(new)*
- `ElementX/Resources/AppIcon.icon/` *(icon assets replaced)*
- `ElementX/Resources/Assets.xcassets/images/` *(new Letro image assets)*
- `compound-ios/Sources/Compound/Icons/CompoundIcon.swift`
- `Tools/SwiftGen/Templates/Strings/structured-swift5-element.stencil`
- `ElementX.xcodeproj/project.pbxproj`
- `ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved`
- `ElementX.xcodeproj/xcshareddata/xcschemes/*.xcscheme` *(scheme renames/updates)*

#### **Impact & Risk**

- **Impact**: Touches app identity, all major screens, the global colour/icon system, the string localisation pipeline, onboarding flow, and build configuration. Any upstream merge must re-apply or carefully reconcile every change. New image assets and the `Letro.strings` override table must be maintained alongside upstream string additions.
- **Risk Level**: `HIGH`. The breadth of changes (authentication screen, string layer, Compound overrides, entitlements) means upstream updates carry a significant merge-conflict and regression risk.

#### **AGPL Relevance**

Not Applicable