Skip to content

Commit e5d7b17

Browse files
NateIsernclaude
andcommitted
Places map: native markers, Google-Maps UX, extended place metadata
Rewrite the Places map screen using native MapLibre style layers instead of MarkerView, switch camera centering to the documented fitBounds(ne, sw, padding, duration) path, and add a Google-Maps- style interaction model: sticky search pill with reanimated drag- synchronised top padding, sticky filter chips, floating grab handle that scrolled rows pass behind, haptic feedback on selection, and an in-app Bloom Prompt for the permission-denied dialog. Extend the Place data model with minimumSpend, acceptsFairToFiat, localCurrency, fiatPayoutMethods, maxFiatPayout, and openingHours; surface them in a new PlaceFacts block inside the detail view. Migrate FlatList → FlashList in contacts and language screens and the deprecated BottomSheetFlashList wrapper to the documented useBottomSheetScrollableCreator hook. Splash screen now uses the transparent adaptive-icon-foreground asset. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 73f0933 commit e5d7b17

9 files changed

Lines changed: 1334 additions & 276 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Built with Expo SDK 55, React Native 0.83, and pure TypeScript cryptography.
1717
- **Masternode** — detect 5,000 FAIR collateral UTXOs, start masternodes
1818
- **FastSend** — instant confirmation via masternode quorum (SwiftTX)
1919
- **BIP38** — encrypted private key export/import
20+
- **Places map** — native MapLibre map of places that accept FairCoin, with category filters, search, minimum-spend and FairCoin-to-fiat exchange metadata per place (native-only; web shows an empty state)
2021
- **Secure** — keys in OS keychain, per-wallet SQLite databases, edge-to-edge UI
2122

2223
## Platforms
@@ -38,6 +39,10 @@ Built with Expo SDK 55, React Native 0.83, and pure TypeScript cryptography.
3839
| Crypto | `@noble/secp256k1` 2.x, `@noble/hashes` 1.8, `@scure/bip32` 1.7, `@scure/bip39` 1.6 |
3940
| Storage | expo-secure-store (native keychain), expo-sqlite (chain data) |
4041
| P2P | Custom SPV client over TCP (react-native-tcp-socket on mobile, Node.js net on Electron) |
42+
| Map | `@maplibre/maplibre-react-native` v10 with Carto vector tiles (no API key) |
43+
| UI kit | `@oxyhq/bloom` (theme, prompt dialogs) |
44+
| Lists | `@shopify/flash-list` v2 with `@gorhom/bottom-sheet` v5 integration |
45+
| Animation | `react-native-reanimated` 4.x |
4146
| Desktop | Electron with custom `app://` protocol for proper SPA routing |
4247

4348
## FairCoin Protocol
@@ -138,6 +143,8 @@ FAIRWallet/
138143
│ ├── contacts.tsx # Address book
139144
│ ├── coin-control.tsx # UTXO selection
140145
│ ├── export-key.tsx # BIP38 key export
146+
│ ├── map.tsx # Native places map (MapLibre + bottom sheet)
147+
│ ├── map.web.tsx # Web fallback (map is native-only)
141148
│ ├── transaction/ # Transaction detail
142149
│ ├── onboarding/ # Welcome, create, restore, PIN setup
143150
│ └── (tabs)/ # Main app (wallet, send, receive, settings)

app.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"userInterfaceStyle": "automatic",
1010
"newArchEnabled": true,
1111
"splash": {
12-
"image": "./assets/splash-icon.png",
12+
"image": "./assets/adaptive-icon-foreground.png",
1313
"resizeMode": "contain",
1414
"backgroundColor": "#1b1e09"
1515
},
@@ -47,11 +47,11 @@
4747
"expo-local-authentication",
4848
"expo-system-ui",
4949
["expo-splash-screen", {
50-
"image": "./assets/splash-icon.png",
50+
"image": "./assets/adaptive-icon-foreground.png",
5151
"imageWidth": 200,
5252
"backgroundColor": "#1b1e09",
5353
"dark": {
54-
"image": "./assets/splash-icon.png",
54+
"image": "./assets/adaptive-icon-foreground.png",
5555
"backgroundColor": "#1b1e09"
5656
}
5757
}],

app/contacts.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import {
1111
TextInput,
1212
Pressable,
1313
Modal,
14-
FlatList,
1514
ScrollView,
1615
} from "react-native";
1716
import { SafeAreaView } from "react-native-safe-area-context";
1817
import { useLocalSearchParams, useRouter } from "expo-router";
1918
import * as Clipboard from "expo-clipboard";
2019
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
20+
import { FlashList } from "@shopify/flash-list";
2121
import { useContactsStore } from "../src/wallet/contacts-store";
2222
import { getDatabase } from "../src/wallet/wallet-store";
2323
import type { ContactRow } from "../src/storage/database";
@@ -587,7 +587,7 @@ export default function ContactsScreen() {
587587
/>
588588
</View>
589589
) : (
590-
<FlatList
590+
<FlashList
591591
data={displayContacts}
592592
renderItem={renderItem}
593593
keyExtractor={keyExtractor}

app/language.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ import {
1212
Text,
1313
TextInput,
1414
Pressable,
15-
FlatList,
16-
type ListRenderItem,
1715
} from "react-native";
1816
import { SafeAreaView } from "react-native-safe-area-context";
1917
import { useRouter } from "expo-router";
2018
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
19+
import { FlashList, type ListRenderItem } from "@shopify/flash-list";
2120
import { useTheme } from "@oxyhq/bloom/theme";
2221
import { EmptyState, ScreenHeader } from "../src/ui/components";
2322
import { SUPPORTED_LANGUAGES, t, type LanguageOption } from "../src/i18n";
@@ -191,7 +190,7 @@ export default function LanguageScreen() {
191190
<EmptyState icon="magnify" title={t("language.noResults")} />
192191
</View>
193192
) : (
194-
<FlatList
193+
<FlashList
195194
data={filtered}
196195
renderItem={renderItem}
197196
keyExtractor={keyExtractor}

0 commit comments

Comments
 (0)