diff --git a/apps/gg/index.html b/apps/gg/index.html index ca568f9d..d0f9dcf1 100644 --- a/apps/gg/index.html +++ b/apps/gg/index.html @@ -6,11 +6,9 @@ let g_data = ${data}; - - -
+ \ No newline at end of file diff --git a/apps/gg/script.js b/apps/gg/script.js index cecacded..dd103a12 100644 --- a/apps/gg/script.js +++ b/apps/gg/script.js @@ -24,6 +24,9 @@ class GgAppElement extends LitElement { world: {type: Object}, id: {type: String}, status: {type: Object}, + tab: {type: String}, + url: {type: String}, + currency: {type: Number}, }; } @@ -37,7 +40,9 @@ class GgAppElement extends LitElement { this.min_lon = Number.MAX_VALUE; this.max_lat = -Number.MAX_VALUE; this.max_lon = -Number.MAX_VALUE; + this.focus = undefined; this.status = undefined; + this.tab = 'map'; this.load().catch(function(e) { console.log('load error', e); }); @@ -46,6 +51,7 @@ class GgAppElement extends LitElement { async load() { console.log('load'); this.user = await tfrpc.rpc.getUser(); + this.url = (await tfrpc.rpc.url()).split('?')[0]; try { await this.update_credentials(); } catch (e) { @@ -84,8 +90,8 @@ class GgAppElement extends LitElement { async get_activities_from_ssb() { this.status = {text: 'loading activities'}; this.loaded_activities = []; - let blob_ids = await tfrpc.rpc.query(` - SELECT json_extract(mention.value, '$.link') AS blob_id + let rows = await tfrpc.rpc.query(` + SELECT messages.author, json_extract(mention.value, '$.link') AS blob_id FROM messages_fts('"gg-activity"') JOIN messages ON messages.rowid = messages_fts.rowid, json_each(messages.content, '$.mentions') as mention @@ -94,15 +100,26 @@ class GgAppElement extends LitElement { ORDER BY messages.timestamp DESC `, []); this.status = {text: 'loading activity data'}; - let blobs = await this.promise_all(blob_ids.map(x => tfrpc.rpc.get_blob(x.blob_id)), 8); + let authors = rows.map(x => x.author); + let blobs = await this.promise_all(rows.map(x => tfrpc.rpc.get_blob(x.blob_id)), 8); this.status = {text: 'processing activity data'}; - for (let blob of blobs) { + for (let [index, blob] of blobs.entries()) { + let activity; try { - this.loaded_activities.push(JSON.parse(blob)); + activity = JSON.parse(blob); } catch { - this.loaded_activities.push(gpx_parse(blob)); + activity = gpx_parse(blob); + } + if (activity) { + activity.author = authors[index]; + this.loaded_activities.push(activity); } } + this.status = {text: 'calculating balance'}; + rows = await tfrpc.rpc.query(` + SELECT count(*) AS currency FROM messages WHERE author = ? AND json_extract(content, '$.type') = 'gg-activity' + `, [this.id]); + this.currency = rows[0].currency; this.status = undefined; this.update_map(); } @@ -278,8 +295,14 @@ class GgAppElement extends LitElement { } async update_map() { + let map = this.shadowRoot.getElementById('map'); + if (!map || !this.loaded_activities.length) { + this.leaflet = undefined; + this.grid_layer = undefined; + return; + } if (!this.leaflet) { - this.leaflet = L.map('map', {attributionControl: false, maxZoom: 16, bounceAtZoomLimits: false}); + this.leaflet = L.map(map, {attributionControl: false, maxZoom: 16, bounceAtZoomLimits: false}); this.leaflet.on({click: this.on_click.bind(this)}); } let self = this; @@ -295,9 +318,6 @@ class GgAppElement extends LitElement { let degrees = 360.0 / (2 ** coords.z); let ul = bounds.getNorthWest(); let lr = bounds.getSouthEast(); - //context.fillText(JSON.stringify(coords), 0, 12); - //context.fillText(`${Math.round(ul.lat * 100) / 100} ${Math.round(ul.lng * 100) / 100}`, 0, 24); - //context.fillText(`${Math.round(lr.lat * 100) / 100} ${Math.round(lr.lng * 100) / 100}`, 0, 36); let mini = document.createElement('canvas'); mini.width = Math.floor(size.x / 16.0); @@ -307,7 +327,6 @@ class GgAppElement extends LitElement { for (let activity of self.loaded_activities) { self.draw_activity_to_tile(image_data, mini.width, mini.height, ul, lr, activity); } - //mini_context.putImageData(image_data, 0, 0); for (let x = 0; x < mini.width; x++) { for (let y = 0; y < mini.height; y++) { let start = (y * mini.width + x) * 4; @@ -333,10 +352,18 @@ class GgAppElement extends LitElement { this.max_lat = Math.max(this.max_lat, bounds.max.lat); this.max_lon = Math.max(this.max_lon, bounds.max.lng); } - this.leaflet.fitBounds([ - [this.min_lat, this.min_lon], - [this.max_lat, this.max_lon], - ]); + if (this.focus) { + this.leaflet.fitBounds([ + this.focus.min, + this.focus.max, + ]); + this.focus = undefined; + } else { + this.leaflet.fitBounds([ + [this.min_lat, this.min_lon], + [this.max_lat, this.max_lon], + ]); + } } activity_to_color(activity) { @@ -529,29 +556,101 @@ class GgAppElement extends LitElement { input.click(); } - render() { - if (!this.user?.credentials?.session?.name) { - return html`
Please login to Tilde Friends, first.
`; + updated() { + this.update_map(); + } + + focus_map(activity) { + let bounds = this.activity_bounds(activity); + if (bounds.min.lat < bounds.max.lat && + bounds.min.lng < bounds.max.lng) { + this.tab = 'map'; + this.focus = bounds; } - if (!this.strava?.access_token) { + } + + render_news() { + return html` + + `; + } + + render_store() { + return html` +

Store

+
Your balance: ${this.currency}
+ `; + } + + render() { + let header; + if (!this.user?.credentials?.session?.name) { + header = html`
Please login to Tilde Friends, first.
`; + } else if (!this.strava?.access_token) { let strava_url = `https://www.strava.com/oauth/authorize?client_id=${k_client_id}&redirect_uri=${k_redirect_url}&response_type=code&approval_prompt=auto&scope=activity%3Aread&state=${g_data.state}`; - return html` -
+ header = html` +
Please login to Strava.
${this.id}
`; + } else { + header = html` +
+
+

Welcome, ${this.user.credentials.session.name}

+ ${this.id} + +
+

${this.status?.text} ${this.status?.value}

+
+ `; + } + + let navigation = html` + + + `; + + let content; + switch (this.tab) { + case 'map': + content = html`
`; + break; + case 'news': + content = this.render_news(); + break; + case 'friends': + content = html`
Friends
`; + break; + case 'store': + content = this.render_store(); + break; } return html` -
-
-

Welcome, ${this.user.credentials.session.name}

- ${this.id} - -
-

${this.status?.text} ${this.status?.value}

+ +
+ ${header} +
${content}
+ ${navigation}
`; }