From dabdaece208f24f6ce77cc5580cf05cfbfaba39e Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Fri, 31 Jul 2020 18:51:12 -0600
Subject: [PATCH] Add support for dynamic thumbnails

Fixes https://github.com/turt2live/matrix-media-repo/issues/146
---
 CHANGELOG.md                                             | 1 +
 common/config/conf_domain.go                             | 1 +
 common/config/conf_main.go                               | 1 +
 common/config/models_domain.go                           | 1 +
 config.sample.yaml                                       | 6 ++++++
 controllers/thumbnail_controller/thumbnail_controller.go | 4 ++++
 util/math.go                                             | 7 +++++++
 7 files changed, 21 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24945173..8865247e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 * Add apng image support. Thanks @Sorunome!
 * Experimental support for Redis as a cache (in preparation for proper load balancing/HA support).
 * Added oEmbed URL preview support.
+* Added support for dynamic thumbnails.
 
 ### Changed
 
diff --git a/common/config/conf_domain.go b/common/config/conf_domain.go
index 9f7ff5b7..f705b370 100644
--- a/common/config/conf_domain.go
+++ b/common/config/conf_domain.go
@@ -61,6 +61,7 @@ func NewDefaultDomainConfig() DomainRepoConfig {
 				{640, 480},
 				{800, 600},
 			},
+			DynamicSizing: false,
 			Types: []string{
 				"image/jpeg",
 				"image/jpg",
diff --git a/common/config/conf_main.go b/common/config/conf_main.go
index b3b45cd4..d082ff13 100644
--- a/common/config/conf_main.go
+++ b/common/config/conf_main.go
@@ -96,6 +96,7 @@ func NewDefaultMainConfig() MainRepoConfig {
 					{640, 480},
 					{800, 600},
 				},
+				DynamicSizing: false,
 				Types: []string{
 					"image/jpeg",
 					"image/jpg",
diff --git a/common/config/models_domain.go b/common/config/models_domain.go
index fd9bf303..39f8d5e8 100644
--- a/common/config/models_domain.go
+++ b/common/config/models_domain.go
@@ -29,6 +29,7 @@ type ThumbnailsConfig struct {
 	Types               []string        `yaml:"types,flow"`
 	MaxAnimateSizeBytes int64           `yaml:"maxAnimateSizeBytes"`
 	Sizes               []ThumbnailSize `yaml:"sizes,flow"`
+	DynamicSizing bool `yaml:"dynamicSizing"`
 	AllowAnimated       bool            `yaml:"allowAnimated"`
 	DefaultAnimated     bool            `yaml:"defaultAnimated"`
 	StillFrame          float32         `yaml:"stillFrame"`
diff --git a/config.sample.yaml b/config.sample.yaml
index 0b0d71f1..81a634d0 100644
--- a/config.sample.yaml
+++ b/config.sample.yaml
@@ -350,6 +350,12 @@ thumbnails:
     - width: 800
       height: 600
 
+  # To allow for thumbnails to be any size, not just in the sizes specified above, set this to
+  # true (default false). When enabled, whatever size requested by the client will be generated
+  # up to a maximum of the largest possible dimensions in the `sizes` list. For best results,
+  # specify only one size in the `sizes` list when this option is enabled.
+  dynamicSizing: false
+
   # The content types to thumbnail when requested. Types that are not supported by the media repo
   # will not be thumbnailed (adding application/json here won't work). Clients may still not request
   # thumbnails for these types - this won't make clients automatically thumbnail these file types.
diff --git a/controllers/thumbnail_controller/thumbnail_controller.go b/controllers/thumbnail_controller/thumbnail_controller.go
index 78ced08b..e1d0d444 100644
--- a/controllers/thumbnail_controller/thumbnail_controller.go
+++ b/controllers/thumbnail_controller/thumbnail_controller.go
@@ -241,6 +241,10 @@ func pickThumbnailDimensions(desiredWidth int, desiredHeight int, desiredMethod
 		}
 	}
 
+	if ctx.Config.Thumbnails.DynamicSizing {
+		return util.MinInt(largestWidth, desiredWidth), util.MinInt(largestHeight, desiredHeight), desiredMethod, nil
+	}
+
 	// Use the largest dimensions available if we didn't find anything
 	if !foundSize {
 		targetWidth = largestWidth
diff --git a/util/math.go b/util/math.go
index 9e460ceb..cb39ce02 100644
--- a/util/math.go
+++ b/util/math.go
@@ -7,6 +7,13 @@ func MaxInt(a int, b int) int {
 	return b
 }
 
+func MinInt(a int, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
 func MinFloat32(a float32, b float32) float32 {
 	if a < b {
 		return a
-- 
GitLab