Compare commits

...

10 Commits

Author SHA1 Message Date
480c97fb9d 1.18.4
All checks were successful
CI / Lint (push) Successful in 29s
CI / Test (push) Successful in 45s
2026-04-02 14:41:19 +04:00
179cf49370 Fix OSM auth not being loaded correctly on launch 2026-04-02 14:40:20 +04:00
aea0388267 1.18.3
All checks were successful
CI / Lint (push) Successful in 29s
CI / Test (push) Successful in 44s
2026-04-02 12:35:40 +04:00
e4d02cda26 Tweak font weight 2026-04-02 12:34:53 +04:00
27ebbaca60 1.18.2
All checks were successful
CI / Lint (push) Successful in 30s
CI / Test (push) Successful in 44s
2026-04-02 12:21:59 +04:00
cbdd056dcb Optimize font-weight for account status 2026-04-02 12:20:53 +04:00
2423b67f94 Use SVG icon for locate-me button 2026-04-02 12:20:37 +04:00
2a3ad26eb9 Prevent OL from loading webfonts for our default font
* Fixes flash of bold text on app launch
* Fixes Noto Sans being used instead of system font where not available
2026-04-02 11:42:19 +04:00
9d06898b15 1.18.1
All checks were successful
CI / Lint (push) Successful in 30s
CI / Test (push) Successful in 44s
2026-04-01 19:26:05 +04:00
6df43edbf9 Fix OSM client ID missing in release build 2026-04-01 19:25:16 +04:00
12 changed files with 42 additions and 14 deletions

3
.env.production Normal file
View File

@@ -0,0 +1,3 @@
# OpenStreetMap OAuth
VITE_OSM_CLIENT_ID=jIn8l5mT8FZOGYiIYXG1Yvj_2FZKB9TJ1edZwOJPsRU
VITE_OSM_OAUTH_URL=https://www.openstreetmap.org

View File

@@ -284,7 +284,9 @@ export default class MapComponent extends Component {
const initialCenter = toLonLat(view.getCenter()); const initialCenter = toLonLat(view.getCenter());
this.mapUi.updateCenter(initialCenter[1], initialCenter[0]); this.mapUi.updateCenter(initialCenter[1], initialCenter[0]);
apply(this.mapInstance, 'https://tiles.openfreemap.org/styles/liberty'); apply(this.mapInstance, 'https://tiles.openfreemap.org/styles/liberty', {
webfonts: 'data:text/css,',
});
this.searchOverlayElement = document.createElement('div'); this.searchOverlayElement = document.createElement('div');
this.searchOverlayElement.className = 'search-pulse'; this.searchOverlayElement.className = 'search-pulse';
@@ -392,7 +394,10 @@ export default class MapComponent extends Component {
const locateElement = document.createElement('div'); const locateElement = document.createElement('div');
locateElement.className = 'ol-control ol-locate'; locateElement.className = 'ol-control ol-locate';
const locateBtn = document.createElement('button'); const locateBtn = document.createElement('button');
locateBtn.innerHTML = '⊙'; locateBtn.style.display = 'flex';
locateBtn.style.alignItems = 'center';
locateBtn.style.justifyContent = 'center';
locateBtn.innerHTML = `<span class="icon" style="width: 14px; height: 14px; display: flex;">${getIcon('navigation')}</span>`;
locateBtn.title = 'Locate Me'; locateBtn.title = 'Locate Me';
locateElement.appendChild(locateBtn); locateElement.appendChild(locateBtn);

View File

@@ -55,7 +55,7 @@ export default class UserMenuComponent extends Component {
</div> </div>
<div class="account-status"> <div class="account-status">
{{#if @storage.connected}} {{#if @storage.connected}}
{{@storage.userAddress}} <strong>{{@storage.userAddress}}</strong>
{{else}} {{else}}
Not connected Not connected
{{/if}} {{/if}}
@@ -84,7 +84,7 @@ export default class UserMenuComponent extends Component {
</div> </div>
<div class="account-status"> <div class="account-status">
{{#if this.osmAuth.isConnected}} {{#if this.osmAuth.isConnected}}
{{this.osmAuth.userDisplayName}} <strong>{{this.osmAuth.userDisplayName}}</strong>
{{else}} {{else}}
Not connected Not connected
{{/if}} {{/if}}

View File

@@ -7,7 +7,15 @@ class MarcoOsmAuthStorage {
localStorage.setItem('marco:osm_auth_state', serializedState); localStorage.setItem('marco:osm_auth_state', serializedState);
} }
loadState() { loadState() {
return localStorage.getItem('marco:osm_auth_state'); const state = localStorage.getItem('marco:osm_auth_state');
if (!state) return false;
try {
JSON.parse(state);
return state;
} catch (e) {
console.warn('Failed to parse OSM auth state', e);
return false;
}
} }
} }
@@ -45,6 +53,11 @@ export default class OsmAuthService extends Service {
} }
async restoreSession() { async restoreSession() {
try {
await this.oauthClient.ready;
} catch (e) {
console.warn('oauthClient.ready failed', e);
}
const isAuthorized = await this.oauthClient.isAuthorized(); const isAuthorized = await this.oauthClient.isAuthorized();
if (isAuthorized) { if (isAuthorized) {
this.isConnected = true; this.isConnected = true;

View File

@@ -14,6 +14,8 @@ html,
body { body {
height: 100%; height: 100%;
overscroll-behavior: none; /* Prevent pull-to-refresh on mobile */ overscroll-behavior: none; /* Prevent pull-to-refresh on mobile */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
@@ -26,6 +28,7 @@ body {
margin: 0; margin: 0;
font-family: 'Noto Sans', sans-serif; font-family: 'Noto Sans', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: normal;
color: #333; color: #333;
} }
@@ -246,12 +249,15 @@ body {
.account-status { .account-status {
font-size: 0.85rem; font-size: 0.85rem;
font-weight: bold;
color: #898989; color: #898989;
margin-top: 0.35rem; margin-top: 0.35rem;
margin-left: calc(18px + 0.75rem); margin-left: calc(18px + 0.75rem);
} }
.account-status strong {
font-weight: 600;
}
.account-item.disabled { .account-item.disabled {
opacity: 0.5; opacity: 0.5;
pointer-events: none; pointer-events: none;
@@ -261,7 +267,6 @@ body {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
font-weight: 500;
} }
.btn-text { .btn-text {

View File

@@ -1,6 +1,6 @@
{ {
"name": "marco", "name": "marco",
"version": "1.18.0", "version": "1.18.4",
"private": true, "private": true,
"description": "Unhosted maps app", "description": "Unhosted maps app",
"repository": { "repository": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -39,8 +39,8 @@
<meta name="msapplication-TileColor" content="#F6E9A6"> <meta name="msapplication-TileColor" content="#F6E9A6">
<meta name="msapplication-TileImage" content="/icons/icon-144.png"> <meta name="msapplication-TileImage" content="/icons/icon-144.png">
<script type="module" crossorigin src="/assets/main-CqvZua00.js"></script> <script type="module" crossorigin src="/assets/main-0ky279gM.js"></script>
<link rel="stylesheet" crossorigin href="/assets/main-uF6fmHZ4.css"> <link rel="stylesheet" crossorigin href="/assets/main-BF2Ls-fG.css">
</head> </head>
<body> <body>
</body> </body>

View File

@@ -52,6 +52,7 @@ module('Unit | Service | osm-auth', function (hooks) {
// Because restoreSession runs in the constructor, we might need to overwrite it after, but it's async. // Because restoreSession runs in the constructor, we might need to overwrite it after, but it's async.
// Let's just create it, let the original restoreSession fail or do nothing, and then we stub and re-call it. // Let's just create it, let the original restoreSession fail or do nothing, and then we stub and re-call it.
service.oauthClient.ready = Promise.resolve();
service.oauthClient.isAuthorized = async () => true; service.oauthClient.isAuthorized = async () => true;
window.localStorage.setItem('marco:osm_user_display_name', 'CachedName'); window.localStorage.setItem('marco:osm_user_display_name', 'CachedName');
@@ -68,6 +69,7 @@ module('Unit | Service | osm-auth', function (hooks) {
test('it fetches user info when logged in but no cached name', async function (assert) { test('it fetches user info when logged in but no cached name', async function (assert) {
let service = this.owner.factoryFor('service:osm-auth').create(); let service = this.owner.factoryFor('service:osm-auth').create();
service.oauthClient.ready = Promise.resolve();
service.oauthClient.isAuthorized = async () => true; service.oauthClient.isAuthorized = async () => true;
service.oauthClient.getTokens = async () => ({ accessToken: 'fake-token' }); service.oauthClient.getTokens = async () => ({ accessToken: 'fake-token' });
// Ensure localStorage is empty for this key // Ensure localStorage is empty for this key