Skip to content

Commit

Permalink
add settings to media items details page, with ability to rotate images
Browse files Browse the repository at this point in the history
  • Loading branch information
brookgagnon committed Nov 25, 2024
1 parent 3a4c00a commit 13437cc
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 4 deletions.
43 changes: 43 additions & 0 deletions controllers/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,49 @@ public function save()
}
}

/**
* Save additional media properties.
*
* @param id
*
* @route POST /v2/media/properties/(:id:)
*/
public function save_properties()
{
$this->user->require_authenticated();

$id = $this->data('id');
$properties = $this->data('properties');

$media = $this->models->media('get_by_id', ['id' => $id]);

// trigger permission failure if can't edit
if (!$this->user_can_edit($media)) {
$this->user->require_permission('manage_media');
}

$this->models->media('properties', ['id' => $id, 'properties' => $properties]);

return [true, 'Properties saved.'];
}

/**
* Get additional media properties.
*
* @param id
*
* @route GET /v2/media/properties/(:id:)
*/
public function get_properties()
{
$this->user->require_authenticated();

$id = $this->data('id');
$properties = $this->models->media('properties', ['id' => $id]);

return [true, 'Properties.', $properties];
}

/**
* Checks that user can manage versions for media item. Does not return true
* or false, but can throw a permissions error using 'require_permissions'.
Expand Down
18 changes: 16 additions & 2 deletions html/media/details.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<ob-tabs>
<ob-tab data-name="Details">

<div style="display: flex; justify-content: space-between;">
<div>
<h1 id="media_heading" data-t>Media Details</h1>
Expand Down Expand Up @@ -91,7 +90,6 @@ <h1 id="media_heading" data-t>Media Details</h1>
</div>

</div>

</fieldset>
</ob-tab>
<ob-tab data-name="Where Used">
Expand All @@ -101,4 +99,20 @@ <h1>Where is this media used?</h1>
</ul>
</div>
</ob-tab>
<ob-tab data-name="Settings">
<h1>Media Settings</h1>
<div id="media_details_settings_saved" class="obwidget message hidden success" data-type="message">Settings saved.
</div>
<div class="media_details_settings" hidden data-type="image">
<h2>Image Rotate</h2>
</div>
<div class="media_details_settings" hidden data-type="none">
<p>There are currently no settings available for this media type.</p>
</div>
<fieldset class="media_details_settings_save" hidden>
<div class="fieldrow">
<button class="add" onclick="OB.MediaDetails.saveSettings()">Save</button>
</div>
</fieldset>
</ob-tab>
</ob-tabs>
49 changes: 48 additions & 1 deletion js/media/details.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
*/

// media details page
OB.Media.detailsPage = function (id) {
OB.MediaDetails = {};
OB.MediaDetails.currentId = null;
OB.MediaDetails.page = function (id) {
OB.MediaDetails.currentId = id;
OB.API.post("media", "get", { id: id, where_used: true }, function (response) {
if (response.status == false) return;

Expand All @@ -27,6 +30,26 @@ OB.Media.detailsPage = function (id) {
var item = response.data;
var used = response.data.where_used.used;

if (item?.type == "image") {
OB.API.post("media", "get_properties", { id: id }, function (propertiesResponse) {
const properties = propertiesResponse.data;

const mediaDetailsSettings = document.querySelector('.media_details_settings[data-type="image"]');
mediaDetailsSettings.removeAttribute("hidden");
const imageRotate = document.createElement("ob-field-image-rotate");
// set class
imageRotate.className = "media_details_settings_imagerotate";
imageRotate.dataset.edit = "true";
imageRotate.dataset.id = item.id;
console.log(properties);
imageRotate.value = properties?.rotate ?? 0;
mediaDetailsSettings.appendChild(imageRotate);
document.querySelector(".media_details_settings_save").removeAttribute("hidden");
});
} else {
$('.media_details_settings[data-type="none"]').show();
}

// handle buttons

// we can download if we're the owner, or we have the download_media permission
Expand Down Expand Up @@ -223,3 +246,27 @@ OB.Media.detailsPage = function (id) {
$("#media_details_used").show();
});
};

OB.MediaDetails.saveSettings = async function () {
$("#media_details_settings_saved").hide();

const rotateField = document.querySelector(".media_details_settings_imagerotate");

if (rotateField) {
const data = {};
data.properties = {
rotate: rotateField.value,
};

OB.API.post(
"media",
"save_properties",
{ id: OB.MediaDetails.currentId, properties: data.properties },
function (response) {
if (response.status == true) {
$("#media_details_settings_saved").show();
}
},
);
}
};
2 changes: 1 addition & 1 deletion js/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ OB.Sidebar.contextMenuDownload = function (id) {
};

OB.Sidebar.contextMenuDetailsPage = function (id) {
OB.Media.detailsPage(id);
OB.MediaDetails.page(id);
};

OB.Sidebar.contextMenuVersionPage = function (id, title) {
Expand Down
38 changes: 38 additions & 0 deletions models/media_model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,44 @@ public function validate($args = [])
return [true,$item['local_id']];
}

/**
* Get or set a media property.
*
* @param item
*
* @return id
*/
public function properties($args = [])
{
OBFHelpers::require_args($args, ['id']);
$media_id = $args['id'];
$properties = $args['properties'] ?? null;


$this->db->where('id', $media_id);
$media = $this->db->get_one('media');

if (!$media) {
return false;
}

if ($properties) {
$this->db->where('id', $media_id);
return $this->db->update('media', ['properties' => json_encode($properties)]);
} else {
$properties = $media['properties'];

if ($properties) {
$properties = json_decode($properties, true);
} else {
$properties = [];
}

return $properties;
}
}


/**
* Insert or update a media item.
*
Expand Down
10 changes: 10 additions & 0 deletions routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
"media",
"search"
],
[
"/api/v2/media/properties/(:id:)",
"media",
"get_properties"
],
[
"/api/v2/media/versions/(:media_id:)",
"media",
Expand Down Expand Up @@ -357,6 +362,11 @@
"media",
"save"
],
[
"/api/v2/media/properties/(:id:)",
"media",
"save_properties"
],
[
"/api/v2/media/versions",
"media",
Expand Down
111 changes: 111 additions & 0 deletions ui/fields/imageRotate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { OBField } from "../base/field.js";
import { html, render } from "../vendor.js";

class OBFieldImageRotate extends OBField {
_value = 0;

async renderEdit() {
render(
html`<ob-element-thumbnail
id="media_details_thumbnail"
data-id=${this.dataset.id}
data-rotate=${this._value}
></ob-element-thumbnail>
<div class="controls">
<div class="controls-left"><button>⭯ Left</button></div>
<div class="controls-label">${this._value}°</div>
<div class="controls-right"><button>Right ⭮</button></div>
</div>`,
this.root,
);

this.root.querySelector(".controls-left button").addEventListener("click", this.rotateLeft.bind(this));
this.root.querySelector(".controls-right button").addEventListener("click", this.rotateRight.bind(this));
}

scss() {
return `
ob-element-thumbnail {
max-width: 300px;
aspect-ratio: 1 / 1;
display: block;
border: 1px solid var(--field-background);
border-radius: 5px;
}
ob-element-thumbnail[data-rotate="90"] {
transform: rotate(90deg);
}
ob-element-thumbnail[data-rotate="180"] {
transform: rotate(180deg);
}
ob-element-thumbnail[data-rotate="270"] {
transform: rotate(270deg);
}
.controls {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.controls-left, .controls-right {
flex: 1 1 0;
display: flex;
}
.controls-right {
justify-content: flex-end;
}
:host {
display: inline-block;
input {
color: #2e3436;
font-size: 13px;
border-radius: 2px;
border: 0;
padding: 5px;
width: 250px;
vertical-align: middle;
}
}
`;
}

get value() {
return this._value;
}

set value(value) {
this._value = value;

const thumbnail = this.root.querySelector("ob-element-thumbnail");
if (thumbnail) {
thumbnail.dataset.rotate = value;
}

const label = this.root.querySelector(".controls-label");
if (label) {
label.innerText = `${value}°`;
}
}

rotateLeft() {
let rotate = (parseInt(this._value) - 90) % 360;
if (rotate < 0) {
rotate += 360;
}
this.value = rotate;
}

rotateRight() {
const rotate = (parseInt(this._value) + 90) % 360;
this.value = rotate;
}
}

customElements.define("ob-field-image-rotate", OBFieldImageRotate);
20 changes: 20 additions & 0 deletions updates/20241122.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

class OBUpdate20241122 extends OBUpdate
{
public function items()
{
$updates = [];
$updates[] = 'Add general properties column to media table.';
return $updates;
}

public function run()
{
$this->db->query('
ALTER TABLE `media` ADD COLUMN `properties` TEXT NULL DEFAULT NULL AFTER `dynamic_select`;
');

return true;
}
}

0 comments on commit 13437cc

Please sign in to comment.