Browse Source

Rework map scripts

master
Jan-Lukas Else 1 month ago
parent
commit
921212dacf
  1. 3
      editor_test.go
  2. 2
      go.mod
  3. 4
      go.sum
  4. 13
      postsDb.go
  5. 32
      postsDb_test.go
  6. 2
      queue.go
  7. 93
      templates/assets/js/geomap.js
  8. 26
      templates/assets/js/geotrack.js
  9. 53
      ui.go
  10. 50
      uiComponents.go

3
editor_test.go

@ -38,7 +38,8 @@ func Test_editorPreview(t *testing.T) {
require.Equal(t, websocket.TextMessage, mt)
msgStr := string(msg)
require.Contains(t, msgStr, "<h1>Title")
require.Contains(t, msgStr, "<h1")
require.Contains(t, msgStr, ">Title")
require.Contains(t, msgStr, "<p>Content")
require.Contains(t, msgStr, "Posts")

2
go.mod

@ -43,7 +43,7 @@ require (
github.com/paulmach/go.geojson v1.4.0
github.com/posener/wstest v1.2.0
github.com/pquerna/otp v1.3.0
github.com/samber/lo v1.12.0
github.com/samber/lo v1.13.0
github.com/schollz/sqlite3dump v1.3.1
github.com/snabb/sitemap v1.0.0
github.com/spf13/cast v1.4.1

4
go.sum

@ -410,8 +410,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4 h1:Ha8xCaq6ln1a+R91Km45Oq6lPXj2Mla6CRJYcuV2h1w=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/samber/lo v1.12.0 h1:UZXQYR2N6FST+QWxnjV7gPmT9KkXL9eWbZxkrefVs88=
github.com/samber/lo v1.12.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A=
github.com/samber/lo v1.13.0 h1:82AIN+opOjdaP2pntOu8UxK1Zp0OyjJrOTMFb44YF1o=
github.com/samber/lo v1.13.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A=
github.com/schollz/sqlite3dump v1.3.1 h1:QXizJ7XEJ7hggjqjZ3YRtF3+javm8zKtzNByYtEkPRA=
github.com/schollz/sqlite3dump v1.3.1/go.mod h1:mzSTjZpJH4zAb1FN3iNlhWPbbdyeBpOaTW0hukyMHyI=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=

13
postsDb.go

@ -290,12 +290,13 @@ func (a *goBlog) undeletePost(path string) error {
}
func (db *database) replacePostParam(path, param string, values []string) error {
// Filter empty values
values = lo.Filter(values, func(v string, _ int) bool { return v != "" })
// Lock post creation
db.pcm.Lock()
defer db.pcm.Unlock()
// Build SQL
sqlBuilder := bufferpool.Get()
defer bufferpool.Put(sqlBuilder)
var sqlArgs = []any{dbNoCache}
// Start transaction
sqlBuilder.WriteString("begin;")
@ -304,15 +305,15 @@ func (db *database) replacePostParam(path, param string, values []string) error
sqlArgs = append(sqlArgs, path, param)
// Insert new post parameters
for _, value := range values {
if value != "" {
sqlBuilder.WriteString("insert into post_parameters (path, parameter, value) values (?, ?, ?);")
sqlArgs = append(sqlArgs, path, param, value)
}
sqlBuilder.WriteString("insert into post_parameters (path, parameter, value) values (?, ?, ?);")
sqlArgs = append(sqlArgs, path, param, value)
}
// Commit transaction
sqlBuilder.WriteString("commit;")
// Execute
if _, err := db.exec(sqlBuilder.String(), sqlArgs...); err != nil {
_, err := db.exec(sqlBuilder.String(), sqlArgs...)
bufferpool.Put(sqlBuilder)
if err != nil {
return err
}
// Update FTS index

32
postsDb_test.go

@ -5,6 +5,7 @@ import (
"testing"
"time"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -362,3 +363,34 @@ func Test_usesOfMediaFile(t *testing.T) {
assert.Equal(t, 2, counts[0])
}
}
func Test_replaceParams(t *testing.T) {
app := &goBlog{
cfg: createDefaultTestConfig(t),
}
_ = app.initDatabase(false)
defer app.db.close()
err := app.db.savePost(&post{
Path: "/test/abc",
Content: "ABC",
Parameters: map[string][]string{
"test": {
"ABC", "DEF", "GHI",
},
},
}, &postCreationOptions{new: true})
require.NoError(t, err)
err = app.db.replacePostParam("/test/abc", "test", []string{"DEF", "123", "456"})
require.NoError(t, err)
p, err := app.getPost("/test/abc")
require.NoError(t, err)
if assert.NotNil(t, p) {
assert.Len(t, p.Parameters["test"], 3)
union := lo.Union(p.Parameters["test"], []string{"DEF", "123", "456"})
assert.Len(t, union, 3)
}
}

2
queue.go

@ -93,7 +93,7 @@ func (a *goBlog) listenOnQueue(queueName string, wait time.Duration, process que
for !done {
qi, err := a.peekQueue(ctx, queueName)
if err != nil {
log.Println("queue peek error:", err.Error())
// log.Println("queue peek error:", err.Error())
continue
}
if qi == nil {

93
templates/assets/js/geomap.js

@ -1,37 +1,68 @@
(function () {
let mapEl = document.getElementById('map')
let locations = (mapEl.dataset.locations == "") ? [] : JSON.parse(mapEl.dataset.locations)
let tracks = (mapEl.dataset.tracks == "") ? [] : JSON.parse(mapEl.dataset.tracks)
let map = L.map('map', {
minZoom: mapEl.dataset.minzoom,
maxZoom: mapEl.dataset.maxzoom
})
L.tileLayer("/-/tiles/{s}/{z}/{x}/{y}.png", {
attribution: mapEl.dataset.attribution,
}).addTo(map)
let features = []
locations.forEach(loc => {
features.push(L.marker([loc.Lat, loc.Lon]).addTo(map).on('click', function () {
window.open(loc.Post, '_blank').focus()
}))
})
tracks.forEach(track => {
track.Paths.forEach(path => {
features.push(L.polyline(path.map(point => [point.Lat, point.Lon]), { color: 'blue' }).addTo(map).on('click', function () {
window.open(track.Post, '_blank').focus()
}))
function loadMap() {
// Get the map element
let mapEl = document.getElementById('map')
// Read the map data
// Map page
let locations = !mapEl.dataset.locations ? [] : JSON.parse(mapEl.dataset.locations)
let tracks = !mapEl.dataset.tracks ? [] : JSON.parse(mapEl.dataset.tracks)
// Post map
let paths = !mapEl.dataset.paths ? [] : JSON.parse(mapEl.dataset.paths)
let points = !mapEl.dataset.points ? [] : JSON.parse(mapEl.dataset.points)
// Create Leaflet map
let map = L.map('map', {
minZoom: mapEl.dataset.minzoom,
maxZoom: mapEl.dataset.maxzoom
})
track.Points.forEach(point => {
features.push(L.marker([point.Lat, point.Lon]).addTo(map).on('click', function () {
window.open(track.Post, '_blank').focus()
// Set tile source and attribution
L.tileLayer("/-/tiles/{s}/{z}/{x}/{y}.png", {
attribution: mapEl.dataset.attribution,
}).addTo(map)
// Add features to the map
let features = []
locations.forEach(loc => {
features.push(L.marker([loc.Lat, loc.Lon]).addTo(map).on('click', function () {
window.open(loc.Post, '_blank').focus()
}))
})
})
tracks.forEach(track => {
track.Paths.forEach(path => {
features.push(L.polyline(path.map(point => [point.Lat, point.Lon]), { color: 'blue' }).addTo(map).on('click', function () {
window.open(track.Post, '_blank').focus()
}))
})
track.Points.forEach(point => {
features.push(L.marker([point.Lat, point.Lon]).addTo(map).on('click', function () {
window.open(track.Post, '_blank').focus()
}))
})
})
paths.forEach(path => {
features.push(L.polyline(path.map(point => [point.Lat, point.Lon]), { color: 'blue' }).addTo(map))
})
points.forEach(point => {
features.push(L.marker([point.Lat, point.Lon]).addTo(map))
})
// Make the map fit the features
map.fitBounds(L.featureGroup(features).getBounds(), { padding: [5, 5] })
}
// Add Leaflet to the page
// CSS
let css = document.createElement('link')
css.rel = 'stylesheet'
css.href = '/-/leaflet/leaflet.css'
document.head.appendChild(css)
map.fitBounds(L.featureGroup(features).getBounds(), { padding: [5, 5] })
// JS
let script = document.createElement('script')
script.src = '/-/leaflet/leaflet.js'
script.onload = loadMap
document.head.appendChild(script)
})()

26
templates/assets/js/geotrack.js

@ -1,26 +0,0 @@
(function () {
let mapEl = document.getElementById('map')
let paths = (mapEl.dataset.paths == "") ? [] : JSON.parse(mapEl.dataset.paths)
let points = (mapEl.dataset.points == "") ? [] : JSON.parse(mapEl.dataset.points)
let map = L.map('map', {
minZoom: mapEl.dataset.minzoom,
maxZoom: mapEl.dataset.maxzoom
})
L.tileLayer("/-/tiles/{s}/{z}/{x}/{y}.png", {
attribution: mapEl.dataset.attribution,
}).addTo(map)
let features = []
paths.forEach(path => {
features.push(L.polyline(path.map(point => [point.Lat, point.Lon]), { color: 'blue' }).addTo(map))
})
points.forEach(point => {
features.push(L.marker([point.Lat, point.Lon]).addTo(map))
})
map.fitBounds(L.featureGroup(features).getBounds(), { padding: [5, 5] })
})()

53
ui.go

@ -11,17 +11,14 @@ import (
)
func (a *goBlog) renderEditorPreview(hb *htmlBuilder, bc *configBlog, p *post) {
if p.RenderedTitle != "" {
hb.writeElementOpen("h1")
hb.writeEscaped(p.RenderedTitle)
hb.writeElementClose("h1")
}
a.renderPostTitle(hb, p)
a.renderPostMeta(hb, p, bc, "preview")
if p.Content != "" {
hb.writeElementOpen("div")
a.postHtmlToWriter(hb, p, true)
hb.writeElementClose("div")
}
// a.renderPostGPX(hb, p, bc)
a.renderPostTax(hb, p, bc)
}
@ -585,11 +582,6 @@ func (a *goBlog) renderGeoMap(hb *htmlBuilder, rd *renderData) {
hb, rd,
func(hb *htmlBuilder) {
a.renderTitleTag(hb, rd.Blog, "")
if !gmd.noLocations {
hb.writeElementOpen("link", "rel", "stylesheet", "href", "/-/leaflet/leaflet.css")
hb.writeElementOpen("script", "src", "/-/leaflet/leaflet.js")
hb.writeElementClose("script")
}
},
func(hb *htmlBuilder) {
hb.writeElementOpen("main")
@ -859,11 +851,6 @@ func (a *goBlog) renderPost(hb *htmlBuilder, rd *renderData) {
if su := a.shortPostURL(p); su != "" {
hb.writeElementOpen("link", "rel", "shortlink", "href", su)
}
if p.HasTrack() {
hb.writeElementOpen("link", "rel", "stylesheet", "href", "/-/leaflet/leaflet.css")
hb.writeElementOpen("script", "src", "/-/leaflet/leaflet.js")
hb.writeElementClose("script")
}
},
func(hb *htmlBuilder) {
hb.writeElementOpen("main", "class", "h-entry")
@ -872,11 +859,7 @@ func (a *goBlog) renderPost(hb *htmlBuilder, rd *renderData) {
hb.writeElementOpen("data", "value", a.getFullAddress(p.Path), "class", "u-url hide")
hb.writeElementClose("data")
// Title
if p.RenderedTitle != "" {
hb.writeElementOpen("h1", "class", "p-name")
hb.writeEscaped(p.RenderedTitle)
hb.writeElementClose("h1")
}
a.renderPostTitle(hb, p)
// Post meta
a.renderPostMeta(hb, p, rd.Blog, "post")
// Post actions
@ -924,35 +907,7 @@ func (a *goBlog) renderPost(hb *htmlBuilder, rd *renderData) {
hb.writeElementClose("div")
}
// GPS Track
if p.HasTrack() {
if track, err := a.getTrack(p); err == nil && track != nil && track.HasPoints {
// Track stats
hb.writeElementOpen("p")
if track.Name != "" {
hb.writeElementOpen("strong")
hb.writeEscaped(track.Name)
hb.writeElementClose("strong")
hb.write(" ")
}
if track.Kilometers != "" {
hb.write("🏁 ")
hb.writeEscaped(track.Kilometers)
hb.write(" ")
hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "kilometers"))
hb.write(" ")
}
if track.Hours != "" {
hb.write("⏱ ")
hb.writeEscaped(track.Hours)
}
hb.writeElementClose("p")
// Map
hb.writeElementOpen("div", "id", "map", "class", "p", "data-paths", track.PathsJSON, "data-points", track.PointsJSON, "data-minzoom", track.MinZoom, "data-maxzoom", track.MaxZoom, "data-attribution", track.MapAttribution)
hb.writeElementClose("div")
hb.writeElementOpen("script", "defer", "", "src", a.assetFileName("js/geotrack.js"))
hb.writeElementClose("script")
}
}
a.renderPostGPX(hb, p, rd.Blog)
// Taxonomies
a.renderPostTax(hb, p, rd.Blog)
hb.writeElementClose("article")

50
uiComponents.go

@ -415,3 +415,53 @@ func (a *goBlog) renderPagination(hb *htmlBuilder, blog *configBlog, hasPrev, ha
hb.writeElementClose("p")
}
}
func (*goBlog) renderPostTitle(hb *htmlBuilder, p *post) {
if p == nil || p.RenderedTitle == "" {
return
}
hb.writeElementOpen("h1", "class", "p-name")
hb.writeEscaped(p.RenderedTitle)
hb.writeElementClose("h1")
}
func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) {
if p == nil || !p.HasTrack() {
return
}
track, err := a.getTrack(p)
if err != nil || track == nil || !track.HasPoints {
return
}
// Track stats
hb.writeElementOpen("p")
if track.Name != "" {
hb.writeElementOpen("strong")
hb.writeEscaped(track.Name)
hb.writeElementClose("strong")
hb.write(" ")
}
if track.Kilometers != "" {
hb.write("🏁 ")
hb.writeEscaped(track.Kilometers)
hb.write(" ")
hb.writeEscaped(a.ts.GetTemplateStringVariant(b.Lang, "kilometers"))
hb.write(" ")
}
if track.Hours != "" {
hb.write("⏱ ")
hb.writeEscaped(track.Hours)
}
hb.writeElementClose("p")
// Map
hb.writeElementOpen(
"div", "id", "map", "class", "p",
"data-paths", track.PathsJSON,
"data-points", track.PointsJSON,
"data-minzoom", track.MinZoom, "data-maxzoom", track.MaxZoom,
"data-attribution", track.MapAttribution,
)
hb.writeElementClose("div")
hb.writeElementOpen("script", "defer", "", "src", a.assetFileName("js/geomap.js"))
hb.writeElementClose("script")
}

Loading…
Cancel
Save