diff --git a/src/Model/Item.php b/src/Model/Item.php index a5a02de0be..f24771375d 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -28,7 +28,6 @@ use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\System; -use Friendica\Model\Tag; use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; @@ -3003,6 +3002,7 @@ class Item $a = DI::app(); Hook::callAll('prepare_body_init', $item); + // In order to provide theme developers more possibilities, event items // are treated differently. if ($item['object-type'] === Activity\ObjectType::EVENT && isset($item['event-id'])) { @@ -3061,6 +3061,7 @@ class Item $item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? ''); $item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']); + self::putInCache($item); $item['body'] = $body; $s = $item["rendered-html"]; @@ -3095,6 +3096,7 @@ class Item ]; Hook::callAll('prepare_body', $hook_data); $s = $hook_data['html']; + unset($hook_data); if (!$attach) { @@ -3134,10 +3136,131 @@ class Item $hook_data = ['item' => $item, 'html' => $s]; Hook::callAll('prepare_body_final', $hook_data); - return $hook_data['html']; } + /** + * @param array $images + * @return string + * @throws \Friendica\Network\HTTPException\ServiceUnavailableException + */ + public static function makeImageGrid(array $images): string + { + $landscapeimages = array(); + $portraitimages = array(); + + foreach ($images as $image) { + ($image['attachment']['width'] > $image['attachment']['height']) ? ($landscapeimages[] = $image) : ($portraitimages[] = $image); + } + + // Image for first column (fc) and second column (sc) + $images_fc = array(); + $images_sc = array(); + $lcount = count($landscapeimages); + $pcount = count($portraitimages); + if ($lcount == 0 || $pcount == 0) { + if ($lcount == 0) { + // only portrait + for ($i = 0; $i < $pcount; $i++) { + ($i % 2 == 0) ? ($images_fc[] = $portraitimages[$i]) : ($images_sc[] = $portraitimages[$i]); + } + } + if ($pcount == 0) { + // ony landscapes + for ($i = 0; $i < $lcount; $i++) { + ($i % 2 == 0) ? ($images_fc[] = $landscapeimages[$i]) : ($images_sc[] = $landscapeimages[$i]); + } + } + } else { + // Mix of landscape and portrait images. + if ($lcount == $pcount) { + // equal amount of landscapes and portraits + for ($l = 0; $l < $lcount; $l++) { + if ($l % 2 == 0) { + $images_fc[] = $landscapeimages[$l]; + $images_fc[] = $portraitimages[$l]; + } else { + $images_sc[] = $portraitimages[$l]; + $images_sc[] = $landscapeimages[$l]; + } + } + } + if ($lcount > $pcount) { + // More landscapes than portraits + $p = 0; + $l = 0; + while ($l < $lcount) { + if (($lcount > $l + 1) && ($pcount > $l)) { + // we have one more landscape that can be used for the l-th portrait + $images_fc[] = $landscapeimages[$l++]; + } + $images_fc[] = $landscapeimages[$l++]; + if ($pcount > $p) { + $images_sc[] = $portraitimages[$p++]; + } + + } + } + if ($lcount < $pcount) { + // More portraits than landscapes + if ($lcount % 2 == 0 && $pcount % 2 == 0) { + /* + * even number of landscapes and portraits, but fewer landscapes than portraits. Iterate to the end + * of landscapes array + */ + $i = 0; + while ($i < $lcount) { + if ($i % 2 == 0) { + $images_fc[] = $landscapeimages[$i]; + $images_fc[] = $portraitimages[$i]; + } else { + $images_sc[] = $portraitimages[$i]; + $images_sc[] = $landscapeimages[$i]; + } + $i++; + } + // Rest portraits + while ($i < $pcount) { + if ($i % 2 == 0) { + $images_fc[] = $portraitimages[$i]; + } else { + $images_sc[] = $portraitimages[$i]; + } + $i++; + } + + } + if ($lcount % 2 != 0 && $pcount % 2 == 0) { + // uneven landscapes count even portraits count. + for ($p = 0; $p < $pcount; $p++) { + // --> First all portraits until + if ($p % 2 == 0) { + $images_fc[] = $portraitimages[$p]; + } else { + $images_sc[] = $portraitimages[$p]; + } + } + // and now the (uneven) landscapes + for ($l = 0; $l < $lcount; $l++) { + // --> First all portraits until + if ($l % 2 == 0) { + $images_fc[] = $landscapeimages[$l]; + } else { + $images_sc[] = $landscapeimages[$l]; + } + } + } + } + } + + return Renderer::replaceMacros(Renderer::getMarkupTemplate('content/image_grid.tpl'), [ + 'columns' => [ + 'fc' => $images_fc, + 'sc' => $images_sc, + ], + ]); + } + /** * Check if the body contains a link * @@ -3289,16 +3412,21 @@ class Item } } - foreach ($images as $image) { - $media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/image.tpl'), [ - '$image' => $image, + $media = ''; + if (count($images) > 1) { + $media = self::makeImageGrid($images); + } + elseif (count($images) == 1) { + $media = $media = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/image.tpl'), [ + '$image' => $images[0], ]); - // On Diaspora posts the attached pictures are leading - if ($item['network'] == Protocol::DIASPORA) { - $leading .= $media; - } else { - $trailing .= $media; - } + } + + // On Diaspora posts the attached pictures are leading + if ($item['network'] == Protocol::DIASPORA) { + $leading .= $media; + } else { + $trailing .= $media; } if ($shared) { diff --git a/view/global.css b/view/global.css index 4101f0fe0a..81a1ba2095 100644 --- a/view/global.css +++ b/view/global.css @@ -680,3 +680,33 @@ span.required { audio { width: 100%; } + +/** + * Image grid settings START + **/ +.imagegrid-row { + display: -ms-flexbox; /* IE10 */ + display: flex; + -ms-flex-wrap: wrap; /* IE10 */ + flex-wrap: wrap; + padding: 0 4px; + box-sizing: border-box; +} + +/* Create four equal columns that sits next to each other */ +.imagegrid-column { + -ms-flex: 50%; /* IE10 */ + flex: 50%; + max-width: 50%; + padding: 0 4px; + box-sizing: border-box; +} + +.imagegrid-column img { + margin-top: 8px; + vertical-align: middle; + width: 100%; +} +/** + * Image grid settings END + **/ \ No newline at end of file diff --git a/view/templates/content/image_grid.tpl b/view/templates/content/image_grid.tpl new file mode 100644 index 0000000000..95e49ee3e1 --- /dev/null +++ b/view/templates/content/image_grid.tpl @@ -0,0 +1,12 @@ +
+
+ {{foreach $columns.fc as $img}} + {{include file="content/image.tpl" image=$img}} + {{/foreach}} +
+
+ {{foreach $columns.sc as $img}} + {{include file="content/image.tpl" image=$img}} + {{/foreach}} +
+
\ No newline at end of file