Closed f321x closed 1 year ago
Hey @f321x thank you for bringing this up.
It is already possible to do something very very close to what you propose.
The payment methods field is a free text entry. The autocomplete box a faster way to enter your freestyle text, then the payment methods icons are simply parsed from the string. One could write "Face to face Amsterdam" as a payment method. Or even select "F2F" to get the icon and then enter "Amsterdam" However, this is certainly... more of a hack than a feature :) It is not obvious for any user that the F2F method can be used this way (but I've certainly seen this a few times in the order book!). I think we should take F2F seriously and make it more clear.
I was exploring ideas some time ago, but I never got to write them down or implement them. It would be great if:
This will only require the Order
model to have 2 new optional fields: latitude
and longitude
. I think there might be ways we can even embed a very low resolution tiled map within the client. That way we do not include any dependency to third party APIs for positioning.
It's a very cool and exciting idea, a bit challenging but it might not even take too long to be implemented to be honest. It's mostly client side and those 2 new fields for Order
.
Okay, I think this is really a must :D Let's put a 1,000,000 Sats bounty on:
Offers
tab. Ieally if they show the same tooltip of the DepthChart
on hover and take you to the order on click.Cool didn't know the payment method field allows free text, actually elegant but a bit unintuitive.
Looked into implementing this (no promises), Leaflet is probably a lightweight and usable solution? https://leafletjs.com/examples/quick-start/
But i guess embedded maps are more pain- than useful as a low res GeoJson worldmap (borders & city names) is >20mb and resource intensive to render iiuc. Alternatives would be the openstreetmap api (a free/libre project), very detailed, fast (usable on Tor) and probably reliable. Or hosting kind of a map server on the stack and only serving the necessary tiles, probably also performant but more cumbersome to maintain (update mapfiles) and few benefits except independence.
Can you think of other ways of doing this, or which solution would you prefer?
Indeed there are many options!
We could re-tile OpenStreetMap to a very coarse resolution and add it to our static folder. This way the Nodeapp and Android app will self-serve the map and those using the hosted client over TOR will be served the map from the coordinator.
Another cool and straight forward option might be using an SVG map and d3.js (this was suggested by GPT4). In fact, there seems to be an NPM library svgMAP That does something similar, has many features we don't need though. Maybe a map like this is sort of enough to click and get approximate lat/lon? Demo here: https://stephanwagner.me/create-world-map-charts-with-svgmap#svgMapDemoGDP I guess the SVG layer is possibly easy to edit and add points
for the 10 biggest cities in each country (or something like that).
For more context, this is GPT4 full answer to how to create a lightweight map component for a ReactJS app:
Creating a Map component in ReactJS without external dependencies can be a bit challenging since most map libraries like Google Maps or Mapbox have their own API dependencies. However, we can create a simple map using SVG and D3.js, which is a JavaScript library for creating data visualizations. D3.js can also handle geographical data, which makes it possible to create a map.
Please note, this approach will not provide a feature-rich map like Google Maps or Mapbox, but it should be sufficient for a simple use case where you need to click on a map and get latitude and longitude.
Here's a step-by-step approach to creating a Map component in ReactJS:
- Create a new React component and import D3.js
First, create a new component for your map. You can call it MapComponent. Then, import D3.js into your component.
import React, { useEffect, useRef } from 'react'; import * as d3 from 'd3';
- Use D3.js to draw your map
D3.js provides several methods for drawing maps. One of the simplest ways is to use the geoMercator projection, which represents the earth as a flat surface. You can use D3.js to draw a world map using a GeoJSON file that contains the geographical data of the world.
const MapComponent = () => { const ref = useRef(); useEffect(() => { const svg = d3.select(ref.current); const projection = d3.geoMercator(); const path = d3.geoPath().projection(projection); d3.json('/path-to-your-geojson-file.json').then((data) => { svg.selectAll('path') .data(data.features) .enter() .append('path') .attr('d', path); }); }, []); return <svg ref={ref}></svg>; };
- Add an event listener to the map
To get the latitude and longitude when a user clicks on the map, you can add an onclick event listener to the SVG paths. Inside the event handler, you can use the projection.invert method to convert the x and y coordinates of the mouse click event to latitude and longitude.
const MapComponent = () => { const ref = useRef(); useEffect(() => { const svg = d3.select(ref.current); const projection = d3.geoMercator(); const path = d3.geoPath().projection(projection); d3.json('/path-to-your-geojson-file.json').then((data) => { svg.selectAll('path') .data(data.features) .enter() .append('path') .attr('d', path) .on('click', function(event) { const [x, y] = d3.pointer(event); const [lng, lat] = projection.invert([x, y]); console.log(`Latitude: ${lat}, Longitude: ${lng}`); }); }); }, []); return <svg ref={ref}></svg>; };
In this case, when you click on the map, the latitude and longitude of the click location will be logged to the console.
Remember, this is a very basic map and might not be accurate enough for some use cases. If you need a more accurate and feature-rich map, consider using a map library that has external dependencies.
It uses a geojson
as input. For context, svgMAP 's map is 100KB. Here the shapes country by country https://github.com/StephanWagner/svgMap/blob/master/src/js/svgMap.js#L1342
Hello there, I have experience with leaflet and maps in general, there are some free APIs you can use to display OpenStreetMap tiles. Using SVG is way too big or way too inaccurate. I'll investigate what are the best privacy friendly options for using OpenStreetMap (maybe there are proxies through Tor, who knows).
@Reckless-Satoshi I know Ieft my last rewards ticket left (sorry 🥲) but I think I can take care of this one now 😃
There are ways to include your own tile server https://hub.docker.com/r/overv/openstreetmap-tile-server
Here is a super nice website about it https://switch2osm.org/serving-tiles/ , I'm only concerned about the system requirements.
Here is a super nice website about it https://switch2osm.org/serving-tiles/ , I'm only concerned about the system requirements.
Nice resource! Indeed, it seems to be very intensive (specially if we intend the tile server to run on self-hosted nodes that are typically Umbrel / StartOS with low end hardware).
Serving tiles also seem to be a bit of an overkill given that we do not need high precision or contextual information such as street layout, names, elevation, etc. It suffices with high level boundaries of countries or regions and a point cloud that vaguely shows the location of orders at the ~continent scale.
Sharing my answer in the chat:
Ah, my initial thought was something way more specific, like this kind of F2F apps for selling your 2nd hand stuff.
In that case yeah I think that the most specific level you can get is a city neighbourhoods, probably would be easy to get the top 50 as you say.
We dont even need to use a new library, Nivo already provides a svg map. I would focus on having all these files out of the build as external assets to avoid having huge sizes, Ill take a look and see whats the easiest way.
Found this https://ahuseyn.github.io/interactive-svg-maps/ it looks like it contains almost all countries, what about this?
The user selects F2F from the payment methods dropdown
A popup with a world map appears and the user clicks on a country
The map changes to a detailed view of the country
The user picks the approximate location of his home.
A 10km radius circle draws on the map
The user confirms the location and the coordinates are associated to the order
This sounds just perfect! :rocket: The maps you found are great. Also very nice that they are MIT license!
Found a problem with SVG, the image is not defined with world coordinates so there is no way to relate the position the user clicks on with a real world coordinate, the solution for that (and the implemented for nivo's map) is GeoJson.
I found this library with the entire world and all countries https://github.com/AshKyd/geojson-regions/tree/master the only issue is that we lost the regions and provinces, something that anyways we can't use with SVG. I'm open to any other sugestion or help finding out a better geojson for countries 😃
I'm open to any other sugestion or help finding out a better geojson for countries 😃
I think this is very decent compromise. We can probably find or craft ourself geojson for internal borders for the countries that are most used in the future.
Small update: I'm stoping the implemetation of nivo maps, looks like the transformation of the geojson to d3 transforms geo coodinates to x/y coordinates, plus it gets really dificult to obtain the exact point where the user clicks. I'll try out leaflet wich seems to be compatible with geojson.
Is your feature request related to a problem? Please describe. Currently, if i understand correctly, the F2F payment option has no possibility to set a location (eg City or coordinates). This renders the otherwise private and useful payment method fully useless as the trade partner cannot see where the other side is located before accepting the order and paying the bond. In Bisq for example you can see the location of the p2p trade before accepting the offer, so you can only accept it if the location is reachable/useful. This is probably also the reason why there are so few F2F offers active.
Describe the solution you'd like Add a field to enter the location when creating an offer with F2F payment method and show the location in the orderbook either always (maybe if only F2F is accepted) or for example on hover over the F2F icon or when looking at the offer details.
Additional context For example see Bisq where this is being done for a long time.