Skip to content

feat: waiting map accept#1693

Open
cimigree wants to merge 78 commits intodevelopfrom
feat/waiting-map-accept
Open

feat: waiting map accept#1693
cimigree wants to merge 78 commits intodevelopfrom
feat/waiting-map-accept

Conversation

@cimigree
Copy link
Copy Markdown
Contributor

@cimigree cimigree commented Feb 12, 2026

closes #1570
Adds a waiting for map accept screen. In subsequent PRs, I change the name of the screen as it holds UI for the whole sending experience.
Uses a packed version of comapeo/core-react for development purposes
for the text, in the Figma it says "Invite Sent" but I am guessing it is supposed to say Map Sent instead, right?
There is currently no typing for the File that is sent so I have included a ts expect error for now.
Also, when someone does not have a custom map, the find custom map from the backend is throwing an error. Ideally it would not do that.
Or maybe it throws a specific kind of error we can catch? In the meantime, I am just catching it the best I can so the UI works and looks right.

Gregor also added to this PR the backend fixes needed to make this code work, like for starting up the map server.

I added a loading icon when uploading a map file. We didn't used to have this functionality, which was very confusing. I took a guess at the UI. What do you think?

When selecting a device to share, only shows the devices that have the same project open as the sender. The map sharing requires that for it to work, otherwise it errors out.
I also added a line to the Not seeing a Device screen to mention that they need to be on the same project that only shows up if they are sharing maps.

image image

@awana-lockfile-bot
Copy link
Copy Markdown

awana-lockfile-bot bot commented Feb 12, 2026

src/backend/package-lock.json changes

Click to toggle table visibility
Name Status Previous Current
@comapeo/core UPDATED 6.0.2 7.0.1
@comapeo/default-categories UPDATED 1.0.0 1.0.1
@comapeo/ipc UPDATED 7.0.0 8.0.0
@comapeo/map-server UPDATED 1.0.1 1.1.0
@emnapi/core UPDATED 1.4.3 1.9.2
@emnapi/runtime UPDATED 1.4.3 1.9.2
@emnapi/wasi-threads UPDATED 1.0.2 1.2.1
@gmaclennan/zip-reader ADDED - 1.0.0
@napi-rs/wasm-runtime UPDATED 0.2.9 0.2.12
@sqlite.org/sqlite-wasm ADDED - 3.51.2-build8
@tybys/wasm-util UPDATED 0.9.0 0.10.1
ready-resource UPDATED 1.1.1 1.2.0
smp-noto-glyphs ADDED - 1.0.0-pre.0
styled-map-package-api ADDED - 5.0.0-pre.4
wsl-utils REMOVED 0.1.0 -
zip-writer ADDED - 2.2.0

@awana-lockfile-bot
Copy link
Copy Markdown

awana-lockfile-bot bot commented Feb 12, 2026

package-lock.json changes

Summary

Status Count
ADDED 19
UPDATED 10
REMOVED 1
Click to toggle table visibility
Name Status Previous Current
@comapeo/cloud UPDATED 0.3.0 0.4.0
@comapeo/core-react UPDATED 10.0.1 11.0.4
@comapeo/core UPDATED 6.0.2 7.0.1
@comapeo/ipc UPDATED 7.0.0 8.0.0
@comapeo/map-server UPDATED 1.0.1 1.1.0
@gmaclennan/zip-reader ADDED - 1.0.0
@hyperswarm/secret-stream UPDATED 6.8.1 6.9.1
@sqlite.org/sqlite-wasm ADDED - 3.51.2-build8
@turf/bbox-polygon ADDED - 7.3.4
@turf/boolean-point-in-polygon UPDATED 6.5.0 7.3.4
@turf/clone ADDED - 7.3.4
@turf/point-to-line-distance ADDED - 7.3.4
@turf/point-to-polygon-distance ADDED - 7.3.4
@turf/polygon-to-line ADDED - 7.3.4
@turf/projection ADDED - 7.3.4
@turf/rhumb-bearing ADDED - 7.3.4
@turf/rhumb-distance ADDED - 7.3.4
bare-ansi-escapes ADDED - 2.2.3
bare-assert ADDED - 1.2.0
bare-inspect ADDED - 3.1.4
bare-type ADDED - 1.1.0
noise-handshake UPDATED 4.1.0 4.2.0
point-in-polygon-hao ADDED - 1.2.4
ready-resource UPDATED 1.1.2 1.2.0
robust-predicates ADDED - 3.0.3
smp-noto-glyphs ADDED - 1.0.0-pre.0
styled-map-package-api ADDED - 5.0.0-pre.4
typebox UPDATED 1.1.10 1.1.16
wsl-utils REMOVED 0.1.0 -
zip-writer ADDED - 2.2.0

@socket-security
Copy link
Copy Markdown

socket-security bot commented Feb 12, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​osm_borders/​maritime_10000m@​1.1.0501003776100
Addednpm/​@​formatjs/​cli@​6.8.2991004196100
Addednpm/​@​types/​lodash.isequal@​4.5.81001005780100
Addednpm/​@​react-native/​typescript-config@​0.76.91001006397100
Addednpm/​@​react-native/​metro-babel-transformer@​0.76.9991006597100
Addednpm/​@​types/​lint-staged@​13.3.01001006680100
Addednpm/​@​types/​react-native-zeroconf@​0.13.1971006978100
Addednpm/​@​comapeo/​nodejs-mobile-react-native@​18.20.4-26910010092100
Addednpm/​@​types/​react-native-indicators@​0.16.6891007178100
Addednpm/​@​react-native/​metro-config@​0.79.51001007297100
Addednpm/​@​tanstack/​eslint-plugin-query@​5.91.21001007497100
Addednpm/​@​types/​semver@​7.7.11001007581100
Addednpm/​@​react-navigation/​native-stack@​7.3.2110010075100100
Addednpm/​@​comapeo/​core-react@​11.0.4751009198100
Updatednpm/​@​comapeo/​ipc@​7.0.0 ⏵ 8.0.0751009696 +1100
Addednpm/​@​react-navigation/​native@​7.1.28991007599100
Addednpm/​@​mapeo/​mock-data@​5.0.0751009792100
Addednpm/​@​react-navigation/​bottom-tabs@​7.14.0991007699100
Addednpm/​@​comapeo/​cloud@​0.4.0761008890100
Addednpm/​@​formatjs/​intl-pluralrules@​6.2.21001007692100
Addednpm/​@​react-navigation/​stack@​7.7.2991007699100
Addednpm/​@​types/​jest@​30.0.01001007781100
Addednpm/​@​formatjs/​intl-getcanonicallocales@​3.2.11001007791100
Addednpm/​@​babel/​preset-env@​7.28.5971007795100
Addednpm/​@​comapeo/​core@​7.0.1771008498100
Addednpm/​@​types/​mocha@​10.0.101001007780100
Addednpm/​@​formatjs/​intl-locale@​5.2.11001007791100
Addednpm/​@​react-native-vector-icons/​octicons@​20.4.0781008392100
Addednpm/​@​react-native-documents/​picker@​12.0.11001007893100
Addednpm/​@​types/​react@​19.2.71001007990100
Updatednpm/​@​babel/​runtime@​7.27.1 ⏵ 7.28.41001007995100
Addednpm/​@​react-native-vector-icons/​fontisto@​12.4.0791008487100
See 39 more rows in the dashboard

View full report

earlyAccessStore,
appUsageStatsStore,
}: AppProvidersProps) => {
const mapServerListenPromise = React.useMemo(
Copy link
Copy Markdown
Contributor Author

@cimigree cimigree Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to memoize this because I was getting an error:
"Listen method has been called more than once without closing"

  • Happened on force close and restart
    Because the appRpc.mapServer.listen() call was happening on every render of the AppProviders component.
    It was also complaining about needing an argument (hence the empty object)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll have a think about improving the ergonomics of the api for this - it's too easy right now to use it in a way that causes errors.

@socket-security
Copy link
Copy Markdown

socket-security bot commented Feb 12, 2026

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn Critical
Critical CVE: Axios has a NO_PROXY Hostname Normalization Bypass Leads to SSRF

CVE: GHSA-3p68-rc4w-qgx5 Axios has a NO_PROXY Hostname Normalization Bypass Leads to SSRF (CRITICAL)

Affected versions: < 1.15.0

Patched version: 1.15.0

From: package-lock.jsonnpm/@wdio/browserstack-service@9.21.0npm/axios@1.8.4

ℹ Read more on: This package | This alert | What is a critical CVE?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Remove or replace dependencies that include known critical CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/axios@1.8.4. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @browserstack/ai-sdk-node is 100.0% likely obfuscated

Confidence: 1.00

Location: Package overview

From: package-lock.jsonnpm/@wdio/browserstack-service@9.21.0npm/@browserstack/ai-sdk-node@1.5.17

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@browserstack/ai-sdk-node@1.5.17. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @react-native/debugger-frontend is 96.0% likely obfuscated

Confidence: 0.96

Location: Package overview

From: package-lock.jsonnpm/@react-native/debugger-frontend@0.81.5

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@react-native/debugger-frontend@0.81.5. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

)) {
const backendVersion = backendMapeoDependencies[dependency];
if (!backendVersion) continue;
// For file: dependencies, compare just the filename (paths may differ)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it's ok to do this just for tests? That way more pressing, problematic test failures will be visible.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also just comment out the expect during dev until it's ready - we shouldn't be using file dependencies by the time the pr is finished

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or don't run these tests on draft prs

@gmaclennan
Copy link
Copy Markdown
Member

I've update the core-react PR #143 with what I hope is a fix for this issue. Here is an updated tarball with the latest from commit digidem/comapeo-core-react@22f6d95

comapeo-core-react-7.3.0-pre.3-MAP-SHARING.tgz

earlyAccessStore,
appUsageStatsStore,
}: AppProvidersProps) => {
const mapServerListenPromise = React.useMemo(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll have a think about improving the ergonomics of the api for this - it's too easy right now to use it in a way that causes errors.

)) {
const backendVersion = backendMapeoDependencies[dependency];
if (!backendVersion) continue;
// For file: dependencies, compare just the filename (paths may differ)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also just comment out the expect during dev until it's ready - we shouldn't be using file dependencies by the time the pr is finished

)) {
const backendVersion = backendMapeoDependencies[dependency];
if (!backendVersion) continue;
// For file: dependencies, compare just the filename (paths may differ)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or don't run these tests on draft prs

{projectId, receiverDeviceId: deviceId, mapId: 'custom'},
{
onSuccess: result => {
Promise.resolve(result).then(mapShare => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something up with my code here - I'll take a look

@cimigree
Copy link
Copy Markdown
Contributor Author

@gmaclennan
So sorry but getting more fetch/ http type errors.
For the useGetCustomMapInfo: [Error: fetch failed: [start] Cannot convert 'http://127.0.0.1:40461/maps/custom/info' to a Kotlin type.]

And for the sendMapShare: [Error: fetch failed: [start] Cannot convert 'http://127.0.0.1:45635/mapShares' to a Kotlin type.]

The bird thinks:
The fetch implementation in @comapeo/core-react is not compatible with React Native on Android.

But again, I can't figure anything else out so don't know if that is the actual case

@cimigree
Copy link
Copy Markdown
Contributor Author

@gmaclennan
Mostly Good News!
I am using maps from here: https://drive.google.com/drive/folders/19iZUWrlTQIBpqr7MnP0u5E5dmFudJYKt (the QA testing assets)
The first map I uploaded and tried to share was this one:
maplibre-demotiles.smp
It uploaded fine but when I tried to share it I got this error:
[Error: Bounds at 3 must be within max of spherical mercator projection -180,-85.051129,180,85.051129]

But then I tried a couple other maps and they worked with no error to get to the next step. I haven't yet gotten further than that, yet. Sorry.
This works now for the two maps below but not for the first one (see above).

 const mapShare = await sendMapShare({
                  projectId,
                  receiverDeviceId: deviceId,
                  mapId: 'custom',
                });
                navigation.navigate('WaitingForMapAccept', {
                  shareId: mapShare.shareId,
                });

demotiles-z2 (1).smp

And this one:
osm-bright-z6 (1).smp

I am going to continue on to next steps after I clean this up a bit (UI in that background map screen isn't quite right), but I thought you wanted to know about where I was able to get so far.

@cimigree
Copy link
Copy Markdown
Contributor Author

cimigree commented Apr 6, 2026

@ErikSin Sorry for the messy and repeated pushes but I somehow messed up the node_modules/ package lock and had to go back and start from scratch.

@ErikSin
Copy link
Copy Markdown
Contributor

ErikSin commented Apr 6, 2026

Just starting to review, and just noting that my package lock is slightly different when i run npm i. Its just different by one line but we should figure out where the change is coming from. Can you run npm i again and see what happens.

I am using node-v24.13.0 and npm-v11.6.2

@ErikSin
Copy link
Copy Markdown
Contributor

ErikSin commented Apr 7, 2026

We are now also able to share maps between two users who are both IN the same project even if they are ON different projects, so I changed the select device for map sharing accordingly.

This is not working as expected

Screen.Recording.2026-04-06.at.5.05.14.PM.mov

It seems like from one device it doesnt matter if your actively on the project. But for the other device it does matter?

I initially thought it was one of the devices was a particant and not a coordinator, but that doesn't effect the outcome.

I don't know if it matters that much? but weird behaviour none the less

Copy link
Copy Markdown
Contributor

@ErikSin ErikSin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its better, now that we have upgraded core and core react, but its still not working fully as expected. See the videos below, but it seems like my samsung Galaxy A03s is having a lot of troubles sending and recieving the cancel in a timely manner. It also is having trouble finding the other device.

Im not sure what the best way to move forward is. This feature doesn't feel ready to release as is.

Comment on lines +233 to +247
<View style={styles.buttonsContainer}>
{warningInfo.warning !== 'space' && (
<PrimaryButton fullSize text={t(m.accept)} onPress={handleAccept} />
)}
{declineStatus === 'pending' ? (
<Loading size={12} />
) : (
<SecondaryButton
fullSize
text={t(m.decline)}
onPress={handleDecline}
/>
)}
</View>
</View>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This UI is a little off.

  1. for buttons we use a <UIActivtyIndicator/>, not <Loading/>
  2. we need block both button if were going to show a loader, not just the decline button

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

);
};

const handleDecline = () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is taking more than 2 minutes to register on the other phone:

Screen.Recording.2026-04-06.at.5.31.50.PM.mov

? Math.floor((currentTime.getTime() - mapShare.mapShareCreatedAt) / 1000)
: 0;

const cancelShare = React.useCallback(() => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is taking several minutes for the other device to register:

Screen.Recording.2026-04-06.at.5.39.06.PM.mov

}
}, [mapShare, navigation]);

const handleCancel = React.useCallback(() => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some really weird behaviour. The progress bar of the receiving phone seems to be quite far behind. And once the sending phone has completed, I cannot press the cancel button on the receiver phone. In this video i am trying multiple times to press "cancel" and I cannot:

Screen.Recording.2026-04-06.at.5.47.18.PM.mov

@cimigree
Copy link
Copy Markdown
Contributor Author

cimigree commented Apr 7, 2026

Just starting to review, and just noting that my package lock is slightly different when i run npm i. Its just different by one line but we should figure out where the change is coming from. Can you run npm i again and see what happens.

I am using node-v24.13.0 and npm-v11.6.2

yes actually there was a change! So sorry I have no idea why!
This is where it is:
"node_modules/bare-events": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz",
"integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==",
"license": "Apache-2.0",
"peer": true,
"peerDependencies": {
"bare-abort-controller": "*"
},
"peerDependenciesMeta": {
"bare-abort-controller": {
"optional": true
}
}
},

Adds the bolded line.

@ErikSin
Copy link
Copy Markdown
Contributor

ErikSin commented Apr 7, 2026

Just starting to review, and just noting that my package lock is slightly different when i run npm i. Its just different by one line but we should figure out where the change is coming from. Can you run npm i again and see what happens.
I am using node-v24.13.0 and npm-v11.6.2

yes actually there was a change! So sorry I have no idea why! This is where it is: "node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", "peer": true, "peerDependencies": { "bare-abort-controller": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true } } },

Adds the bolded line.

Can you push these changes?

Copy link
Copy Markdown
Contributor

@ErikSin ErikSin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it with an APK, and things do seem to be working better...Im still not convinced that its in a state to release. But i am going to send an APK to QA and let them decide whether the frontend should pause on development (and wait for the backend team to update), or if we can go ahead with merging and releasing as is

{
onSuccess: () => {
navigation.goBack();
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the state is being handled by the parent, you need to get rid of this goBack() i believe

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you leave take this out we just stay on the Waiting for device to Accept Map screen and don't go back when you hit cancel. So, still need to have that navigation go back here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im getting a flash of the waiting For Accept screen though. I thought it was due to this, but maybe its something else. Ill take a video

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen.Recording.2026-04-07.at.3.25.40.PM.mov

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ok. I think it was the UI falling through. The status wasn't any of the above/ specified, so the main UI was showing, which is the waiting screen. But now that I have added the pending status, that will show the loader instead (at least that is what I am seeing).

const {shareId} = route.params;

const mapShare = useSingleSentMapShare({shareId});
const {mutate: cancelMapShare} = useCancelSentMapShare();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need catch the status==='pending' here, can show a loading state when that is true

@cimigree cimigree requested a review from ErikSin April 9, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create new Waiting for Map Accept

3 participants