Skip to content

Commit

Permalink
coordinates field support
Browse files Browse the repository at this point in the history
  • Loading branch information
brookgagnon committed Sep 13, 2024
1 parent c197aa8 commit 370df05
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 32 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.3-20240912
5.3.3-20240913
3 changes: 3 additions & 0 deletions classes/core/obfdb.php
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,9 @@ public function update($table, $data)
foreach ($data as $item => $value) {
if ($value === null) {
$setsql[] = $this->format_table_column($item) . '=NULL';
} elseif (preg_match('/^POINT\(-?\d+(\.\d+)?,-?\d+(\.\d+)?\)$/', $value)) {
// special case for POINT data type (no escape if strictly matches which we know is safe)
$setsql[] = $this->format_table_column($item) . '=' . $value;
} else {
$setsql[] = $this->format_table_column($item) . '=' . $this->format_value($value);
}
Expand Down
34 changes: 34 additions & 0 deletions classes/metadata/coordinates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace OB\Classes\Metadata;

class Coordinates extends \OB\Classes\Base\Metadata
{
public function processRow(&$row)
{
$coordinates = $row['metadata_' . $this->name];
if ($coordinates) {
// unpack binary if needed. note this check is very specific to this application and not a general solution
// the expected binary data is 25 bytes long, and the expected non-binary data is less than that
// note there is a very unlikely edge case if someone sets the default value to be a string of 25 characters (which is not possible via the UI, but could be done via the API)
// TODO this should be fixed with better metadata abstraction
if (strlen($coordinates) == 25) {
$data = unpack('x/x/x/x/corder/Ltype/dlat/dlon', $coordinates);
$coordinates = $data['lat'] . ',' . $data['lon'];
}

$coordinates = explode(',', $coordinates);
if (count($coordinates) == 2) {
$latitude = (float) $coordinates[0];
$longitude = (float) $coordinates[1];
$row['metadata_' . $this->name] = [$latitude, $longitude];

// set, early return.
return;
}
}

// not set or not valid
$row['metadata_' . $this->name] = null;
}
}
20 changes: 11 additions & 9 deletions html/media/metadata_addedit.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

<div>

<obwidget id="metadata_addedit_message" type="message"></obwidget>
<obwidget id="metadata_addedit_message" type="message"></obwidget>

<fieldset>
<legend id="metadata_addedit_heading">New Metadata Field</legend>
Expand Down Expand Up @@ -31,15 +30,15 @@
<ob-option value="tags">Tags</ob-option>
<ob-option value="media">Media</ob-option>
<ob-option value="playlist">Playlist</ob-option>
<!--<ob-option value="coordinates">Coordinates</ob-option>-->
<ob-option value="coordinates">Coordinates</ob-option>
</ob-field-select>
</div>

<div class="fieldrow">
<label class="required" data-t>Options (one per line)</label>
<ob-field-textarea data-edit wrap="off" id="metadata_select_options"></ob-field-textarea>
</div>

<div class="fieldrow">
<label data-t>Suggestions</label>
<ob-tag-input data-suggestions="false" id="metadata_tag_suggestions"></ob-tag-input>
Expand All @@ -66,12 +65,14 @@
<ob-field-select data-edit class="hidden metadata_default metadata_default_bool">
<ob-option value="1">Yes</ob-option>
<ob-option value="0">No</ob-option>
></ob-field-select>
></ob-field-select>
<ob-field-select data-edit class="hidden metadata_default metadata_default_select"></ob-field-select>
<ob-tag-input data-suggestions="false" class="hidden metadata_default metadata_default_tags"></ob-tag-input>
<ob-field-media data-edit data-single class="hidden metadata_default metadata_default_media"></ob-field-media>
<ob-field-playlist data-edit data-single class="hidden metadata_default metadata_default_playlist"></ob-field-playlist>
<ob-field-coordinates data-edit class="hidden metadata_default metadata_default_coordinates"></ob-field-coordinates>
<ob-field-playlist data-edit data-single
class="hidden metadata_default metadata_default_playlist"></ob-field-playlist>
<ob-field-coordinates data-edit
class="hidden metadata_default metadata_default_coordinates"></ob-field-coordinates>
</div>

<div class="fieldrow">
Expand All @@ -83,10 +84,11 @@
<fieldset>
<div class="fieldrow">
<button class="add" id="item_properties_save" onclick="OB.Media.metadataSave();" data-t>Save</button>
<button class="edit_only delete" id="item_properties_delete" onclick="OB.Media.metadataDelete();" data-t>Delete</button>
<button class="edit_only delete" id="item_properties_delete" onclick="OB.Media.metadataDelete();"
data-t>Delete</button>
<button id="item_properties_cancel" onclick="OB.UI.closeModalWindow();" data-t>Cancel</button>
</div>
</fieldset>
</div>

<input type="hidden" id="metadata_addedit_id">
<input type="hidden" id="metadata_addedit_id">
3 changes: 3 additions & 0 deletions models/media_model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,7 @@ public function save($args = [])
$metadata_tags = [];

foreach ($metadata_fields as $metadata_field) {
// TODO proper abstraction using metadata classes
if ($metadata_field['type'] == 'tags') {
$tags = [];
if (!empty($item['metadata_' . $metadata_field['name']])) {
Expand All @@ -1458,6 +1459,8 @@ public function save($args = [])
}
}
$metadata['metadata_' . $metadata_field['name']] = implode(',', $tags);
} elseif ($metadata_field['type'] == 'coordinates') {
$metadata['metadata_' . $metadata_field['name']] = 'POINT(' . implode(',', $item['metadata_' . $metadata_field['name']]) . ')';
} else {
$metadata['metadata_' . $metadata_field['name']] = $item['metadata_' . $metadata_field['name']] ?? null;
}
Expand Down
103 changes: 81 additions & 22 deletions ui/fields/coordinates.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,53 @@ import { html, render } from "../vendor.js";
import { OBField } from "../base/field.js";

class OBFieldCoordinates extends OBField {
#init;
_value = null;
_lat = null;
_lng = null;

#value;
renderEdit() {
let lat = null;
let lng = null;

async connected() {
if (this.#init) {
return;
if (this._lat != null) {
lat = parseFloat(this._lat).toFixed(5);
}
this.#init = true;

this.#value = "";

this.renderComponent().then(() => {});
}
if (this._lng != null) {
lng = parseFloat(this._lng).toFixed(5);
}

renderEdit() {
render(
html` <input id="field" type="text" onchange=${this.#updateValue.bind(this)} value="${this.value}" /> `,
html`
<div id="input">
<div id="lat">
<input
type="text"
placeholder="Latitute"
onchange=${this._updateLat.bind(this)}
value="${lat}"
/>
</div>
<div id="lng">
<input
type="text"
placeholder="Longitude"
onchange=${this._updateLng.bind(this)}
value="${lng}"
/>
</div>
</div>
`,
this.root,
);
}

renderView() {
render(html` <div id="field">${this.value}</div> `, this.root);
if (this._lat != null && this._lng != null) {
render(html` <div>${this._lat}, ${this._lng}</div> `, this.root);
} else {
render(html` <div></div> `, this.root);
}
}

scss() {
Expand All @@ -39,29 +62,64 @@ class OBFieldCoordinates extends OBField {
border-radius: 2px;
border: 0;
padding: 5px;
width: 250px;
width: 75px;
vertical-align: middle;
}
#input {
display: flex;
#lat::after {
content: ',';
padding-right: 10px;
padding-left: 2px;
font-size: 1.2em;
font-weight: bold;
}
}
}
`;
}

#updateValue(event) {
const value = event.target.value;
this.value = value;
_updateLat(event) {
const lat = parseFloat(event.target.value);
if (lat >= -90 && lat <= 90) {
this._lat = lat;
}
this.refresh();
}

_updateLng(event) {
const lng = event.target.value;
if (lng >= -180 && lng <= 180) {
this._lng = lng;
}
this.refresh();
}

get value() {
return this.#value;
return [this._lat, this._lng];
}

set value(value) {
this.#addressCoordinates(value).then((result) => {
this.#value = result;
this.renderComponent();
});
// make sure value is an array of 2 numbers
if (value == null) {
this._lat = null;
this._lng = null;
} else if (Array.isArray(value) && value.length == 2 && !isNaN(value[0]) && !isNaN(value[1])) {
this._lat = value[0];
this._lng = value[1];
} else {
console.warn("Invalid coordinates value: " + value);
}

this.refresh();
}

/*
// TODO address lookup
async #addressCoordinates(address) {
return OB.API.postPromise("metadata", "address_coordinates", { address: address }).then((response) => {
if (response.status) {
Expand All @@ -70,6 +128,7 @@ class OBFieldCoordinates extends OBField {
}
});
}
*/
}

customElements.define("ob-field-coordinates", OBFieldCoordinates);

0 comments on commit 370df05

Please sign in to comment.