Conversation
248f0a5 to
d001a34
Compare
2cfe8f2 to
27ab790
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98da150034
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .credentialFlow<UiAccount.Nostr.Credential>(accountKey) | ||
| .distinctUntilChanged() | ||
| .debounce(30.minutes), |
There was a problem hiding this comment.
Remove 30-minute debounce from Nostr credential stream
Debouncing credentialFlow for 30.minutes delays the initial credential emission, so SwitchingServiceManager cannot construct a NostrService immediately; any withService call will wait for that first value and Nostr timelines/actions can sit loading for up to 30 minutes after startup (and after credential changes).
Useful? React with 👍 / 👎.
| // if case .success = onEnum(of: activeAccountPresenter.state.user) { | ||
| // Tab(value: "more", role: .search) { | ||
| // SecondaryTabsScreen(tabs: tabs.secondary) |
There was a problem hiding this comment.
Restore compact-width navigation to secondary tabs
In the compact-width branch, only tabs.primary are rendered and the More tab path to SecondaryTabsScreen is commented out, while Settings and secondary routes are only added in the regular-width branch; on iPhone-sized layouts this removes access to Settings and all secondary tabs.
Useful? React with 👍 / 👎.
| value.startsWith("nsec1", ignoreCase = true) -> | ||
| RustKeys.parse(raw).use { it.secretKey() } |
There was a problem hiding this comment.
Parse normalized nsec value instead of raw input
This branch checks the normalized value (after stripping nostr:/whitespace) but then parses raw; inputs like nostr:nsec1... or nsec strings with surrounding spaces will be rejected even though normalization was intended to accept them.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds native Nostr support across the shared data layer and all UI targets, while refactoring platform-specific behaviors (deep links, instance detection, secondary tabs, metadata/icons) behind a new PlatformSpec abstraction.
Changes:
- Introduces Nostr account/login, datasource, platform detection/specs, relay management, and test coverage.
- Refactors platform-dependent logic (deep links, instance metadata, icons, secondary tabs) to use
PlatformType.spec. - Adds settings/data export-import, pinned tabs support, and updates Android/Desktop/iOS navigation/UI to surface new capabilities (including Nostr relays).
Reviewed changes
Copilot reviewed 110 out of 124 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| shared/src/commonTest/kotlin/dev/dimension/flare/data/network/nostr/NostrServiceTest.kt | Adds unit tests for Nostr account/timeline mapping. |
| shared/src/commonTest/kotlin/dev/dimension/flare/common/deeplink/DeepLinkMappingTest.kt | Updates tests to use PlatformType.spec.deepLinkPatterns. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/settings/AllTabsPresenter.kt | Switches default/secondary tab generation API. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/settings/AccountManagementPresenter.kt | New presenter to manage accounts + ordering updates. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/rss/RssListWithTabsPresenter.kt | New RSS list + pin-tabs presenter wiring. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/misskey/MisskeyAntennasListWithTabsPresenter.kt | Migrates icon enum to UiIcon. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/list/AllListWithTabsPresenter.kt | Migrates icon enum to UiIcon. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/screen/bluesky/BlueskyFeedsWithTabsPresenter.kt | Migrates icon enum to UiIcon. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/settings/NostrRelaysPresenter.kt | Adds relay CRUD for Nostr credentials. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/login/ServiceSelectPresenter.kt | Adds Nostr login state into service selection. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/login/NostrLoginPresenter.kt | New Nostr login presenter (imports key, adds account). |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/login/InstanceMetadataPresenter.kt | Refactors instance metadata fetching via PlatformSpec. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/home/SecondaryTabsPresenter.kt | New presenter building per-account secondary tabs list. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/home/DeepLinkPresenter.kt | Uses spec-provided deep link patterns. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/compose/ComposeUseCase.kt | Logs compose errors to DebugRepository. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/SettingsPresenter.kt | New unified presenter for settings flows + updates. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/PinTabsPresenter.kt | New generic pin/unpin tabs presenter. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/ImportSettingsPresenter.kt | Adds settings import from JSON export. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/ImportDataPresenter.kt | Adds combined data import (DB + settings). |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/HomeTimelineWithTabsPresenter.kt | Uses spec metadata + platform icon. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/HomeTabsPresenter.kt | Updates secondary tab resolution API usage. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/ExportSettingsPresenter.kt | Adds settings export to JSON. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/ExportDataPresenter.kt | Adds combined data export (DB + settings). |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Nostr.kt | Adds Nostr action menu mapping helpers. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/UiRssSource.kt | Adjusts favicon/logo resolution after logoUrl removal. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/UiIcon.kt | Expands UiIcon enum to cover nav/platform icons (incl. Nostr/X). |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/UiApplication.kt | Adds Nostr application mapping. |
| shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/UiAccount.kt | Adds Nostr account + credential + datasource creation. |
| shared/src/commonMain/kotlin/dev/dimension/flare/model/PlatformType.kt | Adds Nostr platform + introduces PlatformTypeMetadata. |
| shared/src/commonMain/kotlin/dev/dimension/flare/model/PlatformSpec.kt | New platform spec abstraction + helpers (spec, icon, etc.). |
| shared/src/commonMain/kotlin/dev/dimension/flare/di/CommonModule.kt | Registers NostrCache + SettingsRepository in shared DI. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/repository/SettingsRepository.kt | New repository managing appearance/app/tab settings datastores. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/repository/AccountRepository.kt | Adds credential update + closes datasources on removal + spec guest datasource. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/XqtPlatformSpec.kt | New X spec: deep links, secondary tabs, detector, metadata. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/VvoPlatformSpec.kt | New VVo spec: detector, metadata, secondary tabs. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/NostrPlatformSpec.kt | New Nostr spec: detector, metadata stubs. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/MisskeyPlatformSpec.kt | New Misskey spec: deep links, secondary tabs, instance metadata. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/MastodonPlatformSpec.kt | New Mastodon spec: deep links, secondary tabs, instance metadata, guest DS. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/platform/BlueskyPlatformSpec.kt | New Bluesky spec: deep links, secondary tabs, detector. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/xqt/XQTPlatformDetector.kt | Adds X host-based platform detector. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/vvo/VVOPlatformDetector.kt | Adds VVo host-based platform detector. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/nostr/NostrPlatformDetector.kt | Adds Nostr detector for pseudo-host. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/nodeinfo/PlatformDetector.kt | New interface for platform detection strategy. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/nodeinfo/NodeInfoService.kt | Refactors platform detection to use detectors + normalizes host. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/misskey/MisskeyPlatformDetector.kt | Adds Misskey detector via nodeinfo + meta probing. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/mastodon/MastodonPlatformDetector.kt | Adds Mastodon detector via nodeinfo + instance probing. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/network/bluesky/BlueskyPlatformDetector.kt | Adds Bluesky detector via server description. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/model/SettingsExport.kt | New model for settings export payload. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/model/DataExport.kt | New model for combined data export payload. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/model/AppearanceSettings.kt | Moves LocalAppearanceSettings out + tweaks defaults/visibility. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datastore/AppDataStore.kt | Adjusts visibility/accessors for shared datastore fields. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/nostr/StatusDetailRemoteMediator.kt | Adds Nostr status detail/context paging loader. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/nostr/NostrLoader.kt | Adds Nostr user/relation/post loader wiring. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/nostr/NostrDataSource.kt | Implements Nostr authenticated datasource + compose/actions/timelines. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/nostr/NostrCache.kt | Adds cache interface + DB-backed implementation for Nostr. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/microblog/handler/UserHandler.kt | Tightens handler constructor visibility. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/microblog/RecommendInstancePagingSource.kt | Refactors instance icons + adds Nostr recommended instance. |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/microblog/PostEvent.kt | Adds Nostr post events (like/repost/report). |
| shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/mapper/Microblog.kt | Expands user extraction across nested timeline content. |
| shared/src/commonMain/kotlin/dev/dimension/flare/common/deeplink/DeepLinkMapping.kt | Removes old pattern generator (now in PlatformSpecs). |
| shared/src/commonMain/kotlin/dev/dimension/flare/common/SwitchingServiceManager.kt | Adds service manager for credential-driven service swapping. |
| shared/build.gradle.kts | Adds Nostr SDK KMP dependency. |
| iosApp/flare/UI/Screen/SettingsScreen.swift | Moves some settings links out of this screen. |
| iosApp/flare/UI/Screen/SecondaryTabsScreen.swift | Reworks “More/secondary” UI into presenter-driven accounts menu. |
| iosApp/flare/UI/Screen/NostrRelaysScreen.swift | Adds iOS UI to manage Nostr relays. |
| iosApp/flare/UI/Screen/HomeTimelineScreen.swift | Adds secondary menu entry + tab selector menu in toolbar. |
| iosApp/flare/UI/Screen/GroupConfigScreen.swift | Updates icon picker to use UiIcon. |
| iosApp/flare/UI/Screen/DiscoverScreen.swift | Moves account selector into toolbar menu. |
| iosApp/flare/UI/Screen/AccountManagementScreen.swift | Adds Nostr “Manage relays” navigation actions. |
| iosApp/flare/UI/Route/TabItemView.swift | Updates HomeTimelineScreen initializer signature. |
| iosApp/flare/UI/Route/Router.swift | Allows .secondaryMenu as a presented route. |
| iosApp/flare/UI/Route/Route.swift | Adds routes for Nostr relays + secondary menu. |
| iosApp/flare/UI/FlareRoot.swift | Refactors tab/root composition; removes old “More” tab path. |
| iosApp/flare/UI/Component/TabIcon.swift | Updates material icon mapping to use UiIcon. |
| iosApp/flare/UI/Component/Status/StatusView.swift | Adds Nostr platform indicator in status header. |
| iosApp/flare/UI/Component/Status/StatusActionView.swift | Expands UiIcon → SF/asset name mapping (incl. Nostr). |
| iosApp/flare/Assets.xcassets/fa-nostr.symbolset/fa-nostr.symbols.svg | Adds Nostr icon asset. |
| iosApp/flare/Assets.xcassets/fa-nostr.symbolset/Contents.json | Registers Nostr icon asset. |
| iosApp/flare/Assets.xcassets/fa-chevron-down.symbolset/Contents.json | Registers chevron-down symbol asset. |
| gradle/libs.versions.toml | Adds Nostr SDK + ktor websockets to version catalog/bundle. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/settings/SettingsScreen.kt | Adds Nostr “Manage relays” context menu entry. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/settings/NostrRelaysScreen.kt | Adds Desktop UI to manage Nostr relays. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/list/ListScreen.kt | Migrates icon enum to UiIcon. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/home/GroupConfigScreen.kt | Migrates icon picker to UiIcon. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/home/EditTabDialog.kt | Switches icon grid orientation/layout. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/screen/feeds/FeedScreen.kt | Migrates icon enum to UiIcon. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/route/Router.kt | Adds NostrRelays route + migrates icons to UiIcon. |
| desktopApp/src/main/kotlin/dev/dimension/flare/ui/route/Route.kt | Adds Desktop route for Nostr relays screen. |
| desktopApp/src/main/kotlin/dev/dimension/flare/Main.kt | Removes composeUiModule from Koin wiring. |
| desktopApp/src/main/composeResources/values/strings.xml | Adds Nostr relay management strings. |
| compose-ui/src/iosMain/kotlin/dev/dimension/flare/ui/controllers/ComposeUIHelper.kt | Removes composeUiModule registration (uses shared modules only). |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/screen/settings/EditTabPresenter.kt | Migrates available icons to UiIcon. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/screen/login/ServiceSelectionScreenContent.kt | Adds Nostr login UI + uses spec-based icons/agreement URL. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/screen/login/SelectionPresenter.kt | Adds Nostr input presenter state. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/screen/login/NostrInputPresenter.kt | Adds presenter for Nostr key input. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/model/UiListExt.kt | Migrates fallback icons to UiIcon. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/model/PlatformTypeIcon.kt | Adds platform brand icon mapping incl. Nostr. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/icons/MisskeyIcon.kt | Adds Nostr icon vector + refactors Misskey vector building. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/component/status/UiTimelineComponent.kt | Imports icon mapping helper for timeline UI. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/component/status/CommonStatusComponent.kt | Uses platform brandIcon; moves UiIcon mapping out. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/component/UiIconExt.kt | Centralizes UiIcon → ImageVector mapping. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/ui/component/TabIcon.kt | Uses new UiIcon mapping + removes old MaterialIcon mapping. |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/di/ComposeUiModule.kt | Removes redundant DI module (now in shared commonModule). |
| compose-ui/src/commonMain/kotlin/dev/dimension/flare/data/model/LocalAppearanceSettings.kt | Restores composition local for appearance settings in compose-ui. |
| compose-ui/src/commonMain/composeResources/values/strings.xml | Adds Nostr login strings/hints. |
| app/src/main/res/values/strings.xml | Adds Nostr relay management strings (Android). |
| app/src/main/java/dev/dimension/flare/ui/screen/settings/SettingsSelectEntryBuilder.kt | Adds navigation entry for Nostr relays screen. |
| app/src/main/java/dev/dimension/flare/ui/screen/settings/NostrRelaysScreen.kt | Adds Android UI to manage Nostr relays. |
| app/src/main/java/dev/dimension/flare/ui/screen/settings/GuestSettingScreen.kt | Uses platform icon vectors instead of logo URLs. |
| app/src/main/java/dev/dimension/flare/ui/screen/settings/EditTabDialog.kt | Switches icon grid orientation/layout. |
| app/src/main/java/dev/dimension/flare/ui/screen/settings/AccountsScreen.kt | Adds “Manage relays” menu item for Nostr accounts. |
| app/src/main/java/dev/dimension/flare/ui/screen/rss/RssEntryBuilder.kt | Migrates icons to UiIcon. |
| app/src/main/java/dev/dimension/flare/ui/screen/misskey/MisskeyEntryBuilder.kt | Migrates icons to UiIcon. |
| app/src/main/java/dev/dimension/flare/ui/screen/list/ListEntryBuilder.kt | Migrates icons to UiIcon. |
| app/src/main/java/dev/dimension/flare/ui/screen/home/GroupConfigScreen.kt | Switches icon grid orientation + migrates to UiIcon. |
| app/src/main/java/dev/dimension/flare/ui/route/Route.kt | Adds Android route for Nostr relays settings. |
| app/src/main/java/dev/dimension/flare/App.kt | Removes composeUiModule from Koin wiring. |
| app/build.gradle.kts | Adds JNA dependency (AAR) to Android app. |
| .github/workflows/ios.yml | Temporarily disables running allTests in iOS CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| override fun nextActionMenu(): ActionMenu.Item = | ||
| ActionMenu.nostrRepost( | ||
| statusKey = postKey, | ||
| repostEventId = | ||
| if (repostEventId == null) { | ||
| "" | ||
| } else { | ||
| null | ||
| }, | ||
| count = (count + if (repostEventId == null) 1 else -1).coerceAtLeast(0), | ||
| accountKey = accountKey, | ||
| ) | ||
| } | ||
|
|
||
| @Serializable | ||
| data class Like( | ||
| override val postKey: MicroBlogKey, | ||
| val reactionEventId: String?, | ||
| val count: Long = 0, | ||
| val accountKey: MicroBlogKey, | ||
| ) : Nostr, | ||
| UpdatePostActionMenuEvent { | ||
| override fun nextActionMenu(): ActionMenu.Item = | ||
| ActionMenu.nostrLike( | ||
| statusKey = postKey, | ||
| reactionEventId = | ||
| if (reactionEventId == null) { | ||
| "" | ||
| } else { | ||
| null | ||
| }, | ||
| count = (count + if (reactionEventId == null) 1 else -1).coerceAtLeast(0), |
There was a problem hiding this comment.
nextActionMenu() uses an empty string (""") as a placeholder event id to represent the toggled state. If the user taps again before the real event id arrives, the next PostEvent.Nostr.* will carry repostEventId == "" / reactionEventId == "", and NostrDataSource.handle() will treat it as non-null and attempt to delete a status with an empty id. Use an explicit boolean (e.g., reposted/liked) for optimistic UI, or keep the id nullable and add a separate pending flag; at minimum, avoid emitting "" and ensure handlers treat blank ids as null.
| accountRepository | ||
| .credentialFlow<UiAccount.Nostr.Credential>(accountKey) | ||
| .distinctUntilChanged() | ||
| .debounce(30.minutes), | ||
| ioScope, |
There was a problem hiding this comment.
debounce(30.minutes) on the credential flow will delay the initial credential emission (and therefore NostrService creation/connection) by up to 30 minutes, effectively breaking Nostr timelines/login. If the goal is to avoid rapid reconnects after edits, consider removing debounce or using a short debounce (hundreds of ms / a few seconds) and/or applying it only after the initial value (e.g., drop(1) before debounce).
| internal data object NostrPlatformDetector : PlatformDetector { | ||
| override suspend fun detect(host: String): NodeData? { | ||
| if (!host.equals("nostr", ignoreCase = true)) { | ||
| return null | ||
| } | ||
| return NodeData( | ||
| host = host, | ||
| platformType = PlatformType.Nostr, | ||
| software = PlatformType.Nostr.name, | ||
| compatibleMode = false, |
There was a problem hiding this comment.
NostrPlatformDetector doesn't override priority, so it defaults to 0 and will be tried after higher-priority network detectors. For the special pseudo-host "nostr", this means unnecessary network calls (and potentially long failures) before selecting Nostr. Set an explicit high priority and/or consider short-circuiting earlier in NodeInfoService.detectPlatformType for host == "nostr".
| override fun close() { | ||
| job.cancel() | ||
| scope.cancel() | ||
| current.value?.service?.close() | ||
| } |
There was a problem hiding this comment.
close() cancels scope before any pending "retired" close coroutines (launched in init) can finish, which can leak previously-created services during shutdown/switches. Consider closing services deterministically in close() (e.g., capture current/retired entries under the mutex and close them in a finally, or don't cancel the scope until after pending drains/closes complete).
| override val relays = credential.map { it.relays.toImmutableList() } | ||
|
|
||
| override fun addRelay(relay: String) { | ||
| credential.onSuccess { credential -> | ||
| if (relay in credential.relays) return | ||
| val newRelays = credential.relays + relay | ||
| val newCredential = credential.copy(relays = newRelays) | ||
| accountRepository.updateCredential( | ||
| accountKey = accountKey, | ||
| credential = newCredential, | ||
| ) | ||
| } |
There was a problem hiding this comment.
addRelay/removeRelay persist whatever string the user enters. Since NostrService later parses relay strings during service creation, an invalid relay URL can throw and break NostrService initialization (potentially taking the datasource offline). Validate and normalize relay URLs before saving (trim, ensure ws:///wss://, parse with runCatching, de-dup), and consider exposing an error state so the UI can surface validation failures.
| run: ./gradlew allTests | ||
| # temporarily disabled due to https://github.com/rust-nostr/nostr-sdk-ffi/issues/72 | ||
| # - name: Run Tests | ||
| # run: ./gradlew allTests |
There was a problem hiding this comment.
This workflow change disables ./gradlew allTests entirely for iOS CI, which removes a key regression signal for unrelated changes. If possible, scope the disablement to only the affected Nostr-related tests/targets (or gate behind a condition) and/or add a follow-up task to re-enable once the upstream issue is fixed.
| # run: ./gradlew allTests | |
| # run: ./gradlew allTests | |
| - name: Track follow-up to re-enable Gradle allTests | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const issueTitle = 'Re-enable ./gradlew allTests in iOS CI once nostr-sdk-ffi issue #72 is fixed'; | |
| const { owner, repo } = context.repo; | |
| // Search for an existing open issue with this exact title | |
| const searchQuery = `repo:${owner}/${repo} "${issueTitle}" in:title type:issue state:open`; | |
| const searchResult = await github.rest.search.issuesAndPullRequests({ q: searchQuery }); | |
| if (searchResult.data.items.length === 0) { | |
| await github.rest.issues.create({ | |
| owner, | |
| repo, | |
| title: issueTitle, | |
| body: [ | |
| 'The `./gradlew allTests` step in `.github/workflows/ios.yml` is currently disabled', | |
| 'due to the upstream issue [`rust-nostr/nostr-sdk-ffi#72`](https://github.com/rust-nostr/nostr-sdk-ffi/issues/72).', | |
| '', | |
| 'Once that upstream issue is resolved, re-enable the Gradle `allTests` step in the iOS CI workflow', | |
| 'to restore full regression coverage for unrelated changes.' | |
| ].join('\n') | |
| }); | |
| } |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f22f6d00b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @Immutable | ||
| @Serializable | ||
| public enum class PlatformType { | ||
| Nostr, |
There was a problem hiding this comment.
Preserve protobuf enum ordering for PlatformType
Placing Nostr before existing entries renumbers all serialized PlatformType enum values. GuestDataSerializer still reads guest_data.pb with ProtoBuf (shared/.../data/datastore/model/GuestData.kt), so previously persisted guest configs can deserialize to the wrong platform (e.g., old Mastodon ordinal mapping to Nostr), and guest mode then routes to NostrPlatformSpec.guestDataSource, which throws UnsupportedOperationException. This creates upgrade-time breakage for users with stored guest settings until data is reset.
Useful? React with 👍 / 👎.
| val newRelays = credential.relays + relay | ||
| val newCredential = credential.copy(relays = newRelays) |
There was a problem hiding this comment.
Validate relay URL before saving it to credentials
addRelay stores arbitrary non-empty input directly into persisted Nostr credentials, but relay strings are later parsed with RustRelayUrl.parse during NostrService creation. A malformed relay entered once can make service initialization fail in the switching manager path, leaving that Nostr account unable to load timelines or perform actions until the bad value is removed out-of-band. Input should be validated/normalized before persisting.
Useful? React with 👍 / 👎.
fix #1264