Compare commits
16 Commits
v1.8.5
...
41d61be42e
| Author | SHA1 | Date | |
|---|---|---|---|
|
41d61be42e
|
|||
|
06b47d96a7
|
|||
|
e8af959be6
|
|||
|
254e177cbf
|
|||
|
47fbc8e7cf
|
|||
|
4ad0df22e2
|
|||
|
0decb4cf1b
|
|||
|
2193f935cc
|
|||
|
b2b03c0a38
|
|||
|
0be02c5b20
|
|||
|
653e44348c
|
|||
|
8fdc697a17
|
|||
|
d9b2a17b91
|
|||
|
85255318ba
|
|||
|
713d9d53e6
|
|||
|
e0ea0ca988
|
@@ -1,6 +1,6 @@
|
||||
# Project Status: Marco
|
||||
|
||||
**Last Updated:** Sat Jan 24 2026
|
||||
**Last Updated:** Mon Jan 26 2026
|
||||
|
||||
## Project Context
|
||||
|
||||
@@ -21,9 +21,14 @@ We are building **Marco**, a decentralized maps application using **Ember.js** (
|
||||
- **Visuals:** Increased bookmark marker size (Radius 9px) and added a subtle drop shadow.
|
||||
- **Feedback:** Implemented a "pulse" animation (via OpenLayers Overlay) at the click location to visualize the search radius (30m/50m).
|
||||
- **Mobile UX:**
|
||||
- Disabled browser tap highlights (`-webkit-tap-highlight-color: transparent`) to prevent blue flashing on Android.
|
||||
- Disabled "pull-to-refresh" (`overscroll-behavior: none`) on the body to prevent accidental reloads while keeping the sidebar scrollable (`contain`).
|
||||
- **Touch:** Disabled browser tap highlights (`-webkit-tap-highlight-color: transparent`) to prevent blue flashing on Android.
|
||||
- **Scroll:** Disabled "pull-to-refresh" (`overscroll-behavior: none`) on the body to prevent accidental reloads while keeping the sidebar scrollable (`contain`).
|
||||
- **Auto-Pan:** On mobile screens, if a selected pin is obscured by the bottom sheet, the map automatically pans to center the pin in the visible top half of the screen.
|
||||
- **Controls:** Fixed positioning of "Locate" and "Rotate" buttons on mobile by correcting CSS `inset` syntax.
|
||||
- **iOS Polish:**
|
||||
- Prevented input auto-zoom by ensuring `.form-control` font size is `1rem` (16px).
|
||||
- Added `-webkit-text-size-adjust: 100%` to prevent text inflation on rotation.
|
||||
- Set base `body` font size to `16px`.
|
||||
- **Geolocation ("Locate Me"):**
|
||||
- Implemented a "Locate Me" button with robust tracking logic.
|
||||
- **Dynamic Zoom:** Automatically zooms to a level where the accuracy circle covers ~10% of the map (fallback logic handles missing accuracy data).
|
||||
@@ -44,7 +49,7 @@ We are building **Marco**, a decentralized maps application using **Ember.js** (
|
||||
- configured with `maxAge: false` to ensure data freshness.
|
||||
- **Dependencies:** Uses `ulid` and `latlon-geohash` internally.
|
||||
|
||||
### 3. App Infrastructure
|
||||
### 3. App Infrastructure & Build
|
||||
|
||||
- **Services:**
|
||||
- `storage.js`: Initializes RemoteStorage, claims access, enables caching, and sets up the widget. Consumes the new `getPlaces` API.
|
||||
@@ -68,6 +73,11 @@ We are building **Marco**, a decentralized maps application using **Ember.js** (
|
||||
- **Geo Utils:**
|
||||
- `app/utils/geo.js`: Haversine distance calculations.
|
||||
- `app/utils/geohash-coverage.js`: Logic to calculate required 4-char geohash prefixes for a given bounding box.
|
||||
- **Build & DevOps:**
|
||||
- **Icon Generation:** Added `build:icons` script using `magick` and `rsvg-convert` to automate PNG generation from SVG.
|
||||
- **Dependencies:** Documented system requirements (ImageMagick, librsvg) in `README.md`.
|
||||
- **Ember CLI:** Added as dev dependency to support generator commands.
|
||||
- **License:** Added AGPLv3 license.
|
||||
|
||||
### 4. Routing & Data Optimization
|
||||
|
||||
@@ -91,16 +101,17 @@ We are building **Marco**, a decentralized maps application using **Ember.js** (
|
||||
|
||||
## Files Currently in Focus
|
||||
|
||||
- `app/templates/application.gjs`: Core layout and "Outside Click" logic.
|
||||
- `app/components/settings-pane.gjs`: Settings UI.
|
||||
- `app/services/settings.js`: Settings persistence.
|
||||
- `app/styles/app.css`: Mobile CSS fixes (font sizes, control positioning).
|
||||
- `package.json`: New scripts and dependencies.
|
||||
- `README.md`: Updated documentation.
|
||||
|
||||
## Next Steps & Pending Tasks
|
||||
|
||||
1. **Collections/Lists:** Implement ability to organize bookmarks into lists/collections.
|
||||
2. **Linting & Code Quality:** Fix remaining CSS errors, remove inline styles in `map.gjs`, and address unused variables/runloop usage.
|
||||
3. **Performance:** Monitor performance with large datasets (thousands of bookmarks).
|
||||
4. **Testing:** Add automated tests for the geohash coverage, retry logic, and new editing features.
|
||||
1. **Mobile Polish:** Verify "Locate Me" animation on iOS Safari.
|
||||
2. **Collections/Lists:** Implement ability to organize bookmarks into lists/collections.
|
||||
3. **Linting & Code Quality:** Fix remaining CSS errors, remove inline styles in `map.gjs`, and address unused variables/runloop usage.
|
||||
4. **Performance:** Monitor performance with large datasets (thousands of bookmarks).
|
||||
5. **Testing:** Add automated tests for the geohash coverage, retry logic, and new editing features.
|
||||
|
||||
## Technical Constraints
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ To run the script, you need `imagemagick` and `librsvg` installed:
|
||||
|
||||
- [ember.js](https://emberjs.com/)
|
||||
- [remoteStorage.js](https://remotestorage.io/rs.js/docs/)
|
||||
- [@remotestorage/module-places](https://gitea.kosmos.org/raucao/remotestorage-module-places)
|
||||
- [Vite](https://vite.dev)
|
||||
- Development Browser Extensions
|
||||
- [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||
|
||||
@@ -17,6 +17,7 @@ import navigation from 'feather-icons/dist/icons/navigation.svg?raw';
|
||||
import phone from 'feather-icons/dist/icons/phone.svg?raw';
|
||||
import server from 'feather-icons/dist/icons/server.svg?raw';
|
||||
import settings from 'feather-icons/dist/icons/settings.svg?raw';
|
||||
import target from 'feather-icons/dist/icons/target.svg?raw';
|
||||
import user from 'feather-icons/dist/icons/user.svg?raw';
|
||||
import x from 'feather-icons/dist/icons/x.svg?raw';
|
||||
import zap from 'feather-icons/dist/icons/zap.svg?raw';
|
||||
@@ -38,6 +39,7 @@ const ICONS = {
|
||||
phone,
|
||||
server,
|
||||
settings,
|
||||
target,
|
||||
user,
|
||||
x,
|
||||
zap,
|
||||
|
||||
@@ -61,8 +61,8 @@ export default class MapComponent extends Component {
|
||||
});
|
||||
|
||||
// Default view settings
|
||||
let center = [99.05738, 7.55087];
|
||||
let zoom = 13.0;
|
||||
let center = [14.21683569, 27.060114248];
|
||||
let zoom = 2.661;
|
||||
|
||||
// Try to restore from localStorage
|
||||
try {
|
||||
|
||||
@@ -122,7 +122,7 @@ export default class PlacesSidebar extends Component {
|
||||
try {
|
||||
const savedPlace = await this.storage.updatePlace(updatedPlace);
|
||||
console.log('Place updated:', savedPlace.title);
|
||||
|
||||
|
||||
// Notify parent to refresh map/lists
|
||||
if (this.args.onBookmarkChange) {
|
||||
this.args.onBookmarkChange();
|
||||
@@ -148,7 +148,7 @@ export default class PlacesSidebar extends Component {
|
||||
{{on "click" this.clearSelection}}
|
||||
><Icon @name="arrow-left" @size={{20}} @color="#333" /></button>
|
||||
{{else}}
|
||||
<h2>Nearby Places</h2>
|
||||
<h2><Icon @name="target" @size={{20}} @color="#ea4335" /> Nearby</h2>
|
||||
{{/if}}
|
||||
<button type="button" class="close-btn" {{on "click" @onClose}}><Icon
|
||||
@name="x"
|
||||
|
||||
@@ -4,11 +4,12 @@ html,
|
||||
body {
|
||||
height: 100%;
|
||||
overscroll-behavior: none; /* Prevent pull-to-refresh on mobile */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Noto Serif', serif;
|
||||
font-family: 'Noto Serif', sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@@ -225,10 +226,15 @@ body {
|
||||
.sidebar-header h2 {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-content {
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
flex: 1; /* Take up remaining vertical space */
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
@@ -256,7 +262,7 @@ body {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-family: inherit;
|
||||
font-size: 0.95rem;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box; /* Ensure padding doesn't overflow width */
|
||||
}
|
||||
|
||||
@@ -320,6 +326,11 @@ body {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.meta-info p {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.meta-info p:first-child {
|
||||
margin-top: 1.2rem;
|
||||
padding-top: 1.2rem;
|
||||
@@ -359,29 +370,31 @@ body {
|
||||
.places-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin: -1rem -1rem 0 -1rem;
|
||||
}
|
||||
|
||||
.places-list li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.place-item {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #ddd;
|
||||
padding: 0.75rem;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.place-item:hover {
|
||||
background: #e9ecef;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.place-name {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
@@ -427,8 +440,8 @@ body {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
.place-details .place-description {
|
||||
margin-bottom: 1.5rem;
|
||||
.place-details p.place-description {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.place-details .actions {
|
||||
@@ -436,6 +449,7 @@ body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@@ -495,11 +509,15 @@ body {
|
||||
border: 2px solid rgb(255 204 51 / 80%); /* Gold/Yellow to match markers */
|
||||
background: rgb(255 204 51 / 20%);
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
/* Use translate3d for GPU acceleration on iOS */
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
pointer-events: none;
|
||||
animation: pulse 1.5s infinite ease-out;
|
||||
box-sizing: border-box; /* Ensure border is included in width/height */
|
||||
display: none; /* Hidden by default */
|
||||
will-change: transform, opacity;
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.search-pulse.active {
|
||||
@@ -513,12 +531,12 @@ body {
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
transform: translate(-50%, -50%) scale(0.8);
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.8);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(-50%, -50%) scale(1.4);
|
||||
transform: translate3d(-50%, -50%, 0) scale(1.4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "marco",
|
||||
"version": "1.8.5",
|
||||
"version": "1.8.10",
|
||||
"private": true,
|
||||
"description": "Unhosted maps app",
|
||||
"repository": {
|
||||
@@ -50,7 +50,7 @@
|
||||
"@embroider/vite": "^1.5.0",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@glimmer/component": "^2.0.0",
|
||||
"@remotestorage/module-places": "link:vendor/remotestorage-module-places",
|
||||
"@remotestorage/module-places": "1.x",
|
||||
"@rollup/plugin-babel": "^6.1.0",
|
||||
"@warp-drive/core": "~5.8.0",
|
||||
"@warp-drive/ember": "~5.8.0",
|
||||
|
||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -52,8 +52,8 @@ importers:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
'@remotestorage/module-places':
|
||||
specifier: link:vendor/remotestorage-module-places
|
||||
version: link:vendor/remotestorage-module-places
|
||||
specifier: 1.x
|
||||
version: 1.0.0
|
||||
'@rollup/plugin-babel':
|
||||
specifier: ^6.1.0
|
||||
version: 6.1.0(@babel/core@7.28.6)(rollup@4.55.1)
|
||||
@@ -1377,6 +1377,9 @@ packages:
|
||||
resolution: {integrity: sha512-4rdu8GPY9TeQwsYp5D2My74dC3dSVS3tghAvisG80ybK4lqa0gvlrglaSTBxogJbxqHRw/NjI/liEtb3+SD+Bw==}
|
||||
engines: {node: '>=18.12'}
|
||||
|
||||
'@remotestorage/module-places@1.0.0':
|
||||
resolution: {integrity: sha512-vaqJeTw658gjPyLz70Mq2AbGfDZ66O2mpDFME+gtaGFYl2+UvrvRLCrXWHYuyTE21f3TJdegeXM6C5nZMxLv9A==}
|
||||
|
||||
'@rollup/plugin-babel@6.1.0':
|
||||
resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -5180,6 +5183,10 @@ packages:
|
||||
engines: {node: '>=0.8.0'}
|
||||
hasBin: true
|
||||
|
||||
ulid@3.0.2:
|
||||
resolution: {integrity: sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==}
|
||||
hasBin: true
|
||||
|
||||
underscore.string@3.3.6:
|
||||
resolution: {integrity: sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==}
|
||||
|
||||
@@ -6967,6 +6974,11 @@ snapshots:
|
||||
'@pnpm/error': 1000.0.5
|
||||
find-up: 5.0.0
|
||||
|
||||
'@remotestorage/module-places@1.0.0':
|
||||
dependencies:
|
||||
latlon-geohash: 2.0.0
|
||||
ulid: 3.0.2
|
||||
|
||||
'@rollup/plugin-babel@6.1.0(@babel/core@7.28.6)(rollup@4.55.1)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
@@ -11449,6 +11461,8 @@ snapshots:
|
||||
uglify-js@3.19.3:
|
||||
optional: true
|
||||
|
||||
ulid@3.0.2: {}
|
||||
|
||||
underscore.string@3.3.6:
|
||||
dependencies:
|
||||
sprintf-js: 1.1.3
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
release/assets/main-Din37YgL.js
Normal file
2
release/assets/main-Din37YgL.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
release/assets/main-iBIZAPnF.css
Normal file
1
release/assets/main-iBIZAPnF.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,8 +26,8 @@
|
||||
<meta name="msapplication-TileColor" content="#F6E9A6">
|
||||
<meta name="msapplication-TileImage" content="/icons/icon-144.png">
|
||||
|
||||
<script type="module" crossorigin src="/assets/main-DsIm8MXw.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-Csx4lQiv.css">
|
||||
<script type="module" crossorigin src="/assets/main-Din37YgL.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-iBIZAPnF.css">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
||||
1
vendor/remotestorage-module-places
vendored
1
vendor/remotestorage-module-places
vendored
@@ -1 +0,0 @@
|
||||
/home/basti/src/remotestorage/modules/remotestorage-module-places
|
||||
Reference in New Issue
Block a user