-
-
Notifications
You must be signed in to change notification settings - Fork 338
Variable for %GPS in quick chat. Feature request #2653 #3535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@suteny0r Uh thanks, though I'm not sure what for?. 🧐🤨 |
|
AI crap, detekt. Then you can consider trying to hurry us up |
Enables QuickChat messages to include dynamic GPS coordinates using %GPS variable. When a QuickChat action contains %GPS, it is replaced with the current device coordinates in format: latitude,longitude (7 decimal places). Adds default location pin (📍) button as second quick chat action that inserts https://maps.google.com/?q=%GPS which expands to actual coordinates. Changes: - Add userLatitude/userLongitude parameters to QuickChatRow and handleQuickChatAction - Replace %GPS (case-insensitive) with lat,lon when coordinates available - Add locationAction button (position=-2) that appears when GPS valid - Pass GPS coordinates from ourNode validPosition to action handler Example: https://maps.google.com/?q=%GPS becomes https://maps.google.com/?q=25.7987898,-80.3939333
Fixes crash 'Key "0" was already used' when showing QuickChat. Both alertAction and locationAction have default uuid=0L, causing key collision in LazyRow. Changed to use position which is guaranteed unique: bell=-1, location=-2, user actions=0,1,2...
Remove hardcoded location action. Users can now create their own QuickChat action with %GPS variable which will be replaced with actual coordinates. Example: Create QuickChat action with message 'https://maps.google.com/?q=%GPS' and it expands to 'https://maps.google.com/?q=25.7987898,-80.3939333' This allows users to: - Edit the action name (emoji) - Change between Append/Instant mode - Modify the URL or message format - Reorder actions - Delete if not needed
Initialize database with default location pin (📍) QuickChat action when no actions exist. Creates entry with: - Name: 📍 - Message: https://maps.google.com/?q=%GPS - Mode: Append - Position: 0 Users can edit, delete, or reorder this action via QuickChat settings.
Move default location action initialization from QuickChatViewModel to MessageViewModel. MessageViewModel is instantiated when opening a channel, ensuring the default action appears immediately without needing to first open QuickChat settings.
fc03738 to
a7bb96d
Compare
You brought #2653 to my attention (on discord). It was a superior method of achieving the location pin drop that I had submitted, so I rewrote it and resubmitted it. The new method allows the user to modify the map URL to use any map service provider they like. It allows them access to the immediate send selector. In contrast to waypoints, this method allows the user to send to private channels, and to DM individual nodes. It also doesn't have the 'anyone can delete the waypoint I just created' problem. Waypoints in general are just a bad way of communicating position. They are static. If you are travelling, the waypoint you create is a marker showing where you were, at one time, not where you are. Messages are ephemeral. You don't have to go back and clean up the ones you send. Its obvious that a location you drop in a message isn't meant to indicate permanence. |
|
I'm Deeno over there, he's someone else. You still aren't getting green ticks here. Read the contributing.md, run spotless and detekt. delete the unnecessary AI junk, then I'll review it. And stop trying to speed things up while not doing your part. |
Applied automatic code formatting fixes to pass CI checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unused userLatitude and userLongitude parameters from QuickChatRow function - Update detekt baseline to allow 8 parameters in MessageViewModel constructor (needed for quickChatActionRepository dependency injection) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Thanks for bringing that to my attention. |
| action = action, | ||
| messageInputState = messageInputState, | ||
| userLatitude = ourNode?.takeIf { it.validPosition != null }?.latitude, | ||
| userLongitude = ourNode?.takeIf { it.validPosition != null }?.longitude, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this not a named tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now it is.
| onSendMessage: (String) -> Unit, | ||
| ) { | ||
| val processedMessage = | ||
| if (userLatitude != null && userLongitude != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be checking for the presence of the string before it does any other logic.
if message.lower.contains ('%gps')
if <valid gps data>
<do the replace>
if <any other quick message params we want?>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Now it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and now it does, properly.
|
|
||
| LazyRow(modifier = modifier.padding(vertical = 4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp)) { | ||
| items(allActions, key = { it.uuid }) { action -> | ||
| items(allActions, key = { it.position }) { action -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we changing this key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key was changed from uuid to position to fix a crash: Key "0" was already used.
Both the alert bell action and the default location pin action are created with uuid=0L (the default
value). When both are present in the LazyRow, this causes a key collision that crashes the app.
The position field is guaranteed unique:
Bell action: position = -1
Location pin action: position = -2 (or could be 0 if it's user-editable)
User-created actions: position = 0, 1, 2...
This ensures each item in the LazyRow has a unique, stable key for proper Compose recomposition.
| quickChatActionRepository.upsert( | ||
| org.meshtastic.core.database.entity.QuickChatAction( | ||
| name = "📍", | ||
| message = "https://maps.google.com/?q=%GPS", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're not going to serve a google link to the mesh by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I'll make it conditional on whether it's the f-droid or google build to use google maps or openstreetmaps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The layout of the OSM URL required that I separate the %GPS variable into %LAT and %LON. The app now constructs the appropriate URL, depending on whether it is the fdroid or google build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to have a geo intent (geo:47.62148,-122.34814), which the app will highlight. When clicked android opens a list of apps which handle geolocation, and a user can also set a default app.
Geo urls can also be expanded to include other metadata sent to the receiving app, like a label to put on the point, e.g. geo:47.62148,-122.34814(FriendXYZ @ 2025-11-09 16:40).
This format still allows the lat/long to be copied/pasted manually.
Code to send the intent is something like: (note AI assisted example)
fun openLabeledGeoIntent(latitude: Double, longitude: Double, label: String? = null) {
val uriString = if (!label.isNullOrEmpty()) {
"geo:0,0?q=$latitude,$longitude(${Uri.encode(label)})" // Slightly different format than the sending format due to better app support if using a label
} else {
"geo:$latitude,$longitude"
}
val geoUri = Uri.parse(uriString)
val mapIntent = Intent(Intent.ACTION_VIEW, geoUri)
mapIntent.resolveActivity(packageManager)?.let {
startActivity(mapIntent)
}
}Usage:
openLabeledGeoIntent(47.62148, -122.34814, "FriendXYZ @ 2025-11-09 16:40")There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to have a geo intent (
geo:47.62148,-122.34814), which the app will highlight. When clicked android opens a list of apps which handle geolocation, and a user can also set a default app.Geo urls can also be expanded to include other metadata sent to the receiving app, like a label to put on the point, e.g.
geo:47.62148,-122.34814(FriendXYZ @ 2025-11-09 16:40).This format still allows the lat/long to be copied/pasted manually.
Code to send the intent is something like: (note AI assisted example)
fun openLabeledGeoIntent(latitude: Double, longitude: Double, label: String? = null) { val uriString = if (!label.isNullOrEmpty()) { "geo:0,0?q=$latitude,$longitude(${Uri.encode(label)})" // Slightly different format than the sending format due to better app support if using a label } else { "geo:$latitude,$longitude" } val geoUri = Uri.parse(uriString) val mapIntent = Intent(Intent.ACTION_VIEW, geoUri) mapIntent.resolveActivity(packageManager)?.let { startActivity(mapIntent) } }Usage:
openLabeledGeoIntent(47.62148, -122.34814, "FriendXYZ @ 2025-11-09 16:40")
Would this be a less portable way to implement the feature? There is an iOS client as well, which I hope to port this feature to, once the quickchat feature is implemented there. There is also a web client.
Remember, it's just a quickchat message template. It builds the template differently depending on whether the build is for f-droid (OSM) or play store (Google Maps), but the template can be edited to support any mapping service that lets you pass the coordinates as parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar technique on the Meshtastic browser client:
- Sender: (on browser client)
- Sends a Geo URI "I'm at geo:47.62148,-122.34814" message (either from a newly implimented quick chat utilizing a browser's
getCurrentPosition(), or a manually entered message)
- Sends a Geo URI "I'm at geo:47.62148,-122.34814" message (either from a newly implimented quick chat utilizing a browser's
- Receiver: (on browser client)
- Parses the Geo URI
- Creates an
<a herf="..." target="_blank">tag, but uses the existing Meshtastic browser client's geolocation technique:
https://github.com/meshtastic/web/blob/7f21b3b531fce84794d7d417ca7daf0db911a069/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx#L382-L392 - Nothing to do on click, as it's a normal
<a herf="..." target="_blank">tag
Future item: I'd leave it for future fixes, but the linked to code could be further improved by adding a config item to allow the user to select which map service they'd like to use, as there isn't OS handling of geo intents which otherwise gives users control of which map app used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed that the current browser client doesn't make even web urls clickable.
Since the current iOS client doesn't have quick chat yet, it can only view the links, not create them, and the web client can't even view the existing format without copy/paste, switching to this new method wouldn't be impacting the existing audience that much. I will see if I can get it working.
Thanks again for the input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested your newer debug build (on an isolated dev phone); it's working well.
One outlier case, if GPS Mode = DISABLED is set on the node, the "%LAT,%LON" doesn't get replaced with coordinates, producing a sent message of "geo:%LAT,LON":
Though likely the same result, you could also test:
GPS Mode = NOT_PRESENT- Before the node's GPS has a GPS fix
- GPS provided by the phone, which is under
Settings=>App=>Provide phone location to mesh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now, if quick chat message contains variables that require location, button is disabled unless location is available. PR updated. Builds updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removes the Claude Code settings file from version control and adds .claude/ directory to .gitignore to prevent future commits. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove accidentally committed image file from repository. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…URLs Add support for %LAT and %LON variables in QuickChat messages, with automatic substitution of user coordinates. Map URLs are now configured per build variant to respect F-Droid preferences. Changes: - Replace single %GPS variable with %LAT and %LON variables - Add DEFAULT_MAP_URL BuildConfig field with variant-specific URLs: * Google: https://maps.google.com/?q=%LAT,%LON * F-Droid: https://www.openstreetmap.org/?mlat=%LAT&mlon=%LON#map=13/%LAT/%LON - Refactor to use MeshProtos.Position instead of separate lat/lng parameters - Check for variable presence before processing GPS substitution - Update existing location pin URLs when switching between build variants - Add core.common dependency to feature:messaging module - Update detekt baseline for additional MessageViewModel parameter Addresses reviewer feedback: - Use named tuple (Position) instead of separate primitive parameters - Check for variable presence before GPS data lookup - No hardcoded Google Maps URLs in F-Droid builds
This is a complete rewrite based on PR feedback to use the standard geo: URI format instead of variant-specific Google Maps/OpenStreetMap URLs. Changes: - Use geo: URI scheme (RFC 5870) for universal mapping app compatibility - Remove build-variant-specific DEFAULT_MAP_URL from BuildConfig - Add geo: URI pattern recognition to AutoLinkText linkification - Simplify QuickChat location pin to only create default, never update - Template format: geo:%LAT,%LON (coordinates only, no label) Benefits: - Works with all mapping apps (Google Maps, OsmAnd, Organic Maps, etc.) - No build variant differences - single universal format - Cleaner, more maintainable code - Respects user customization of QuickChat actions
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3535 +/- ##
========================================
+ Coverage 0.49% 0.51% +0.01%
========================================
Files 370 376 +6
Lines 22233 21255 -978
Branches 2543 2569 +26
========================================
- Hits 111 109 -2
+ Misses 22101 21126 -975
+ Partials 21 20 -1 ☔ View full report in Codecov by Sentry. |
eb2e20d to
28f269b
Compare
When a QuickChat action requires location data (%LAT or %LON variables), the button is now automatically disabled if no valid GPS position is available. This prevents users from accidentally sending location messages with invalid or missing coordinates. Changes: - Add userPosition parameter to QuickChatRow function - Check if action requires position by detecting %LAT/%LON in message - Disable button when position is required but unavailable - Button remains functional for non-location actions
| val geoPattern = Pattern.compile("geo:[-+]?\\d*\\.?\\d+,[-+]?\\d*\\.?\\d+(?:\\([^)]*\\))?") | ||
| Linkify.addLinks(it, geoPattern, "geo:") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might recommend internally using the geo:0,0?q=47.6062,-122.3321(Our Office) format, due to Google Maps not producing a pin as mentioned in https://en.wikipedia.org/wiki/Geo_URI_scheme#Unofficial_extensions:
Google Maps adopts an unconventional approach to displaying the points: it shows the map for, but does not display a map pin, when a location is given in the standard way. A pin only shows up when given as the query. In other words, to show a pin at the Wikimedia Foundation office, one should not use geo:37.78918,-122.40335 but geo:0,0?q=37.78918,-122.40335.
| val geoPattern = Pattern.compile("geo:[-+]?\\d*\\.?\\d+,[-+]?\\d*\\.?\\d+(?:\\([^)]*\\))?") | |
| Linkify.addLinks(it, geoPattern, "geo:") | |
| val geoPattern = Pattern.compile("geo:([-+]?\\d*\\.?\\d+,[-+]?\\d*\\.?\\d+)(?:\\(([^)]*)\\))?") | |
| // For better support, internally transform to the geo:0,0?q=LATITUDE,LONGITUDE(LABEL) format | |
| val geoTransformFilter = Linkify.TransformFilter { match, url -> | |
| val coordinates = match.group(1) | |
| val label = match.group(2) | |
| "geo:0,0?q=$coordinates" + if (!label.isNullOrEmpty()) "(${Uri.encode(label)})" else "" | |
| } | |
| Linkify.addLinks(spannable, geoPattern, "", null, geoTransformFilter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually wrote it that way to begin with, but ran into complications. "Some vendors, such as Android OS, have adopted extensions to the "geo" URI scheme:" such as the label in parenthesis after the coordinates. This unofficial extension requires URL customizations that in some cases are vendor specific. For example, "To add the label in Google Maps, it will be like: geo:0,0?q=37.78918,-122.40335(Wikimedia+Foundation)" changes it from passing lat and lon as params to turning them into query terms with those params, requiring a placeholder of 0,0 where the coordinates would normally go. When I first wrote support for OSM, in a previous version, it's URL format worked properly when coordinates were passed as parameters, but when converted to a query, using coordinates as search terms, it would often fail displaying errors.
In the end I decided I would rather not make it require specific layouts for particular mapping services, sometimes with conflicting requirements, and to just forego the label. Maybe when it becomes officially part of RFC 5870 it can be made to work across multiple mapping providers in a uniform way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed my mind. The problems I had seen were from browser resolution of a hastily constructed OSM URL. I re-implemented the label to include the shortname, used the unofficial extension format, installed OsmAnd, and tested. It worked perfectly, and it is a lot nicer to have the label.
I'll be updating the PR momentarily. Thanks again for prodding me to make it better.
Since I'm not allowed to post builds on my fork here, if you want to see it you will need to click the 'suteny0r:location-variable' in the header and look in the right sidebar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updates complete
|
@suteny0r don't post releases from your fork |
Enhance geo: URI format to include user's short name as a label using the Google Maps unofficial extension format. Update template to geo:0,0?q=%LAT,%LON(%SNAME) which displays the sender's name when opened in mapping applications. Changes: - Add %SNAME variable replacement for node short name - Update geo: URI regex to support query parameters (?q=...) - Change default template to geo:0,0?q=%LAT,%LON(%SNAME) - Pass ourNode to handleQuickChatAction for name lookup
| private fun linkify(text: String) = Factory.getInstance().newSpannable(text).also { | ||
| LinkifyCompat.addLinks(it, Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES or Linkify.PHONE_NUMBERS) | ||
| // Add geo: URI pattern for location links with optional query params and label in parentheses | ||
| val geoPattern = Pattern.compile("geo:[-+]?\\d*\\.?\\d+,[-+]?\\d*\\.?\\d+(?:\\?[^\\s]*)?") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this match the full "geo:37.7749,-122.4194(foo)"? I think it stops before the '(' as it now requires a '?' char to continue the regex matching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. Impressive catch. Now both forms of the geo: URL get parsed properly. Thanks. release Builds updated.
Improve regex pattern to match geo URIs with labels in both formats: - Direct coordinates with label: geo:lat,lon(label) - Query parameter with label: geo:0,0?q=lat,lon(label) The query parameter portion now excludes closing parenthesis to prevent premature termination when label is present.
Fix regex pattern to properly match geo URIs in both formats: - Direct coordinates with label: geo:lat,lon(label) - Query parameter with label: geo:0,0?q=lat,lon(label) Changed pattern to use [?\(] character class to match either ? or ( as the start of the optional suffix, then [^\s]* to match everything until whitespace. This ensures labels in parentheses are fully captured.
| result.replace("%LAT", latitude, ignoreCase = true).replace("%LON", longitude, ignoreCase = true) | ||
| } | ||
| ourNode?.user?.shortName?.let { shortName -> | ||
| result = result.replace("%SNAME", shortName, ignoreCase = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're going to have an issue with shortnames with a space, among other cases.
The space will break your new regex, and other items like shortName = "<')<" or ">))>" (my poor attempt at a four char ascii art fish), will break the Linkify URL parsing.
You're going to need URI encoding for the label:
| result = result.replace("%SNAME", shortName, ignoreCase = true) | |
| result = result.replace("%SNAME", Uri.encode(shortName), ignoreCase = true) |
But this URI-encodes all uses of %SNAME.
Some options:
- Have a
%SNAMEENC,which URI encodes - Falling back to a
%GEOtoken which directly get replaced with the full"geo:(${latitude),${longitude}(${Uri.encode(label)})"- Granted, I like the flexibility of independent replacement tokens, as I want to emit
"geo:47.62148,-122.34814(FriendXYZ+@+2025-11-09+16:40)", which would be from hypothetical future tokens of"geo:%LAT,%LON(%LNAMEENC+@+$DATE+$TIME)"(timestamp is so folks don't confuse old map pins)
- Granted, I like the flexibility of independent replacement tokens, as I want to emit
- Handeling on the receiver side -- from
geo:47.62148,-122.34814, auto-append a label of who+when, if a label doesn't exist, before sending to Linkify
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I applied your URI encoding change. (I can't believe I didn't think about that before)
I implemented %LNAME (but I did not add it to the template, I like the shorter label on maps)
The pin created is ephemeral (unlike waypoint pins) so adding date/timestamps seems unnecessary, as they only exist for the lifetime of the view session, and the messages they appear in already have a timestamp.
In the context of quick chat messages, it seems redundant to want to include an unencode version of the node name in the message, because every message will already have that (sender).
What sort of failure/fallback cases are you thinking about for the simpler %GEO message use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might I suggest %F0%9F%90%A0 for your fish? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What sort of failure/fallback cases are you thinking about for the simpler %GEO message use?
No failure cases, just mentioning that you can use a %GEO token to produce the full message, and you wouldn't have to worry about when to encode %SNAME.
In your updated code, you're always encoding the %SNAME & the now added %LNAME too. This has the issue of URI encoding when not needed, like with a quick message of "Test message seen by %LNAME in SOMA"; sending %SNAME or %LNAME is useful as most nodes in my list don't have a name, so I assume others likewise don't know my node's name (even more likely for new nodes):
| Web client view | Android client view |
|---|---|
No names for most |
![]() |
The pin created is ephemeral (unlike waypoint pins) so adding date/timestamps seems unnecessary, as they only exist for the lifetime of the view session, and the messages they appear in already have a timestamp.
The pins can be non-ephemeral once in the map apps, directly so if bookmarked, seen in search history, or used as a routing destination. I certainly have a ton of old bookmarked temporary locations.
Message timestamps are lost in store-and-forward; so if you're disconnected from the mesh when someone sends their location, you'll get the stored message automatically when you reconnect but it will have the current timestamp displayed on an hours old message, implying the sender is at that location now. Granted that should be fixed in store-and-forward.
Might I suggest %F0%9F%90%A0 for your fish? :)
I could make a case for spiky boi %F0%9F%90%A1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get it now. People may want to use the variable expansion in quick chat messages other than pin drops. Now I see why the *ENC variants would be useful.
I started out with this being a quick chat mod. currently the variable expansions only happen when quick chat messages are triggered. Should I expand it so that any manually typed messages in the message window can use variable expansions? I don't like making changes to areas outside of the scope of the enhancement, so I'm inclined not to do that.
I noticed that the other variables from your example, $date and $time don't actually work. Were they hypothetical or am I using them wrong?
I see now that it could be useful to ALSO provide a single %GEO expansion with the simple, non labeled version of the geo: URI
I'll go add that back in %GEO for single term expansion, in addition to the current set.
Do you think the URI encoding overhead is significant enough to warrant the complexity of only doing it when the variable is used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started out with this being a quick chat mod. currently the variable expansions only happen when quick chat messages are triggered. Should I expand it so that any manually typed messages in the message window can use variable expansions? I don't like making changes to areas outside of the scope of the enhancement, so I'm inclined not to do that.
I don't have a feel for the Meshtastic repos, but it's likely easier to put in a MVP with a constrained set of tokens, like (%LAT, %LON) or %GEO, touching a minimal area of code, in the first PR. Letting users test the feature, and setting the basis for a discussion on what is useful and a followup of adding those tokens and further functionality.
Couple examples as precedent of a thought-though replacement token & operator scheme:
- Splunk uses a replacement token format of
$token_name|u$w/ the|uafterwards to indicate to URL encode the token value. In splunk,$env:user_realname|u$would be the user's full username with URL encoding operator added.
https://help.splunk.com/en/splunk-cloud-platform/create-dashboards-and-reports/simple-xml-dashboards/10.1.2507/drilldown-and-dashboard-interactivity/token-usage-in-dashboards#token-filters-0 - Mailchimp uses a
*|FNAME|*for the user's firstname and*|URL:FNAME|*as an operator to URL encode the first name
https://mailchimp.com/help/all-the-merge-tags-cheat-sheet
Takeaways from looking at replacement token implementations:
- All had a start AND end deliminator e.g
#{TOKEN}#(Azure Pipelines),$TOKEN$(splunk),*|FNAME|*(mailchimp) - Most use namespaces, e.g.
$server.serverName$(splunk),*|USER:COMPANY|*(Mailchimp) - Most have operators built-into the token to do things like lowercase, url encode, etc:
- Terse: Most are short and combined w/ the token directly
$token_name|u$(splunk), and*|URL:FNAME|*(Mailchimp) - Verbose: ArcGIS has vary verbose style like
<dyn type="mapFrame" name="MapFrameName" property="lowerLeft.x" units="dd.deg" decimalPlaces="2" showDirections="True"/>to get the longitude of the left side of the map rounded to two decimal places"122.31" - None that I saw had free-form scripting language, like
ROUND($LAT$, 2))for its operators
- Terse: Most are short and combined w/ the token directly
I might recommend:
- Start/end deliminators
- Using the namespaces from the Meshtastic protobufs
- Terse operators
E.g. $POSITION:LATITUDE$ and $USER:LONGNAME|U$ for a URL encoded long name. Though something more terse is nice too, like $LNAME|U$.
I noticed that the other variables from your example, $date and $time don't actually work. Were they hypothetical or am I using them wrong?
Hypothetical future tokens.
Do you think the URI encoding overhead is significant enough to warrant the complexity of only doing it when the variable is used?
Not sure what you're asking.
- Add URI encoding for %SNAME and %LNAME to handle special characters and spaces in node names - Add support for %LNAME (long name) variable in QuickChat actions - Add trailing space after appended messages to preserve link clickability - Refactor variable detection to reduce complexity for detekt This ensures geo URIs with node names work correctly even when names contain spaces or special characters like parentheses and angle brackets.




#2653
Implemented %GPS variable for use in quick chat. First run inserts quick chat item for dropping location pin in message. It can be edited or deleted. On first run, if there are no entries in the quick chat table, this entry will be recreated. This also allows the user to change the URL to use any other mapping service instead of Google Maps.
This PR supersedes #3533
Thanks @deeno, good idea.