Commit 648f3338 authored by Saturnino Abril's avatar Saturnino Abril Committed by Harrison Healey

[PLT-6496] Remove System Console and config settings for image height and width (#6688)

* remove System Console and config settings for image height and width

* add constants and update config.json

* updated as per review
parent e1168ab7
......@@ -245,12 +245,6 @@ func trackConfig() {
"driver_name": utils.Cfg.FileSettings.DriverName,
"amazon_s3_ssl": *utils.Cfg.FileSettings.AmazonS3SSL,
"amazon_s3_signv2": *utils.Cfg.FileSettings.AmazonS3SignV2,
"thumbnail_width": utils.Cfg.FileSettings.ThumbnailWidth,
"thumbnail_height": utils.Cfg.FileSettings.ThumbnailHeight,
"preview_width": utils.Cfg.FileSettings.PreviewWidth,
"preview_height": utils.Cfg.FileSettings.PreviewHeight,
"profile_width": utils.Cfg.FileSettings.ProfileWidth,
"profile_height": utils.Cfg.FileSettings.ProfileHeight,
"max_file_size": *utils.Cfg.FileSettings.MaxFileSize,
})
......
......@@ -53,7 +53,10 @@ const (
RotatedCCWMirrored = 7
RotatedCW = 8
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
IMAGE_THUMBNAIL_PIXEL_WIDTH = 120
IMAGE_THUMBNAIL_PIXEL_HEIGTH = 100
IMAGE_PREVIEW_PIXEL_WIDTH = 1024
)
// Similar to s3.New() but allows initialization of signature v2 or signature v4 client.
......@@ -553,18 +556,13 @@ func getImageOrientation(input io.Reader) (int, error) {
}
func generateThumbnailImage(img image.Image, thumbnailPath string, width int, height int) {
thumbWidth := float64(utils.Cfg.FileSettings.ThumbnailWidth)
thumbHeight := float64(utils.Cfg.FileSettings.ThumbnailHeight)
imgWidth := float64(width)
imgHeight := float64(height)
var thumbnail image.Image
if imgHeight < thumbHeight && imgWidth < thumbWidth {
if height < IMAGE_THUMBNAIL_PIXEL_HEIGTH && width < IMAGE_THUMBNAIL_PIXEL_WIDTH {
thumbnail = img
} else if imgHeight/imgWidth < thumbHeight/thumbWidth {
thumbnail = imaging.Resize(img, 0, utils.Cfg.FileSettings.ThumbnailHeight, imaging.Lanczos)
} else if height/width < IMAGE_THUMBNAIL_PIXEL_HEIGTH/IMAGE_THUMBNAIL_PIXEL_WIDTH {
thumbnail = imaging.Resize(img, 0, IMAGE_THUMBNAIL_PIXEL_HEIGTH, imaging.Lanczos)
} else {
thumbnail = imaging.Resize(img, utils.Cfg.FileSettings.ThumbnailWidth, 0, imaging.Lanczos)
thumbnail = imaging.Resize(img, IMAGE_THUMBNAIL_PIXEL_WIDTH, 0, imaging.Lanczos)
}
buf := new(bytes.Buffer)
......@@ -581,8 +579,9 @@ func generateThumbnailImage(img image.Image, thumbnailPath string, width int, he
func generatePreviewImage(img image.Image, previewPath string, width int) {
var preview image.Image
if width > int(utils.Cfg.FileSettings.PreviewWidth) {
preview = imaging.Resize(img, utils.Cfg.FileSettings.PreviewWidth, utils.Cfg.FileSettings.PreviewHeight, imaging.Lanczos)
if width > IMAGE_PREVIEW_PIXEL_WIDTH {
preview = imaging.Resize(img, IMAGE_PREVIEW_PIXEL_WIDTH, 0, imaging.Lanczos)
} else {
preview = img
}
......
......@@ -31,10 +31,11 @@ import (
)
const (
TOKEN_TYPE_PASSWORD_RECOVERY = "password_recovery"
TOKEN_TYPE_VERIFY_EMAIL = "verify_email"
PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
VERIFY_EMAIL_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
TOKEN_TYPE_PASSWORD_RECOVERY = "password_recovery"
TOKEN_TYPE_VERIFY_EMAIL = "verify_email"
PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
VERIFY_EMAIL_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
IMAGE_PROFILE_PIXEL_DIMENSION = 128
)
func CreateUserWithHash(user *model.User, hash string, data string) (*model.User, *model.AppError) {
......@@ -717,13 +718,11 @@ func CreateProfileImage(username string, userId string) ([]byte, *model.AppError
return nil, model.NewLocAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error())
}
width := int(utils.Cfg.FileSettings.ProfileWidth)
height := int(utils.Cfg.FileSettings.ProfileHeight)
color := colors[int64(seed)%int64(len(colors))]
dstImg := image.NewRGBA(image.Rect(0, 0, width, height))
dstImg := image.NewRGBA(image.Rect(0, 0, IMAGE_PROFILE_PIXEL_DIMENSION, IMAGE_PROFILE_PIXEL_DIMENSION))
srcImg := image.White
draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.ZP, draw.Src)
size := float64((width + height) / 4)
size := float64(IMAGE_PROFILE_PIXEL_DIMENSION / 2)
c := freetype.NewContext()
c.SetFont(font)
......@@ -732,7 +731,7 @@ func CreateProfileImage(username string, userId string) ([]byte, *model.AppError
c.SetDst(dstImg)
c.SetSrc(srcImg)
pt := freetype.Pt(width/6, height*2/3)
pt := freetype.Pt(IMAGE_PROFILE_PIXEL_DIMENSION/6, IMAGE_PROFILE_PIXEL_DIMENSION*2/3)
_, err = c.DrawString(initial, pt)
if err != nil {
return nil, model.NewLocAppError("CreateProfileImage", "api.user.create_profile_image.initial.app_error", nil, err.Error())
......@@ -809,7 +808,8 @@ func SetProfileImage(userId string, imageData *multipart.FileHeader) *model.AppE
img = makeImageUpright(img, orientation)
// Scale profile image
img = imaging.Fill(img, utils.Cfg.FileSettings.ProfileWidth, utils.Cfg.FileSettings.ProfileHeight, imaging.Center, imaging.Lanczos)
profileWidthAndHeight := 128
img = imaging.Fill(img, profileWidthAndHeight, profileWidthAndHeight, imaging.Center, imaging.Lanczos)
buf := new(bytes.Buffer)
err = png.Encode(buf, img)
......
......@@ -113,12 +113,6 @@
"Directory": "./data/",
"EnablePublicLink": false,
"PublicLinkSalt": "",
"ThumbnailWidth": 120,
"ThumbnailHeight": 100,
"PreviewWidth": 1024,
"PreviewHeight": 0,
"ProfileWidth": 128,
"ProfileHeight": 128,
"InitialFont": "luximbi.ttf",
"AmazonS3AccessKeyId": "",
"AmazonS3SecretAccessKey": "",
......
......@@ -231,12 +231,6 @@ type FileSettings struct {
Directory string
EnablePublicLink bool
PublicLinkSalt *string
ThumbnailWidth int
ThumbnailHeight int
PreviewWidth int
PreviewHeight int
ProfileWidth int
ProfileHeight int
InitialFont string
AmazonS3AccessKeyId string
AmazonS3SecretAccessKey string
......@@ -1426,30 +1420,6 @@ func (o *Config) IsValid() *AppError {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_driver.app_error", nil, "")
}
if o.FileSettings.PreviewHeight < 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_preview_height.app_error", nil, "")
}
if o.FileSettings.PreviewWidth <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_preview_width.app_error", nil, "")
}
if o.FileSettings.ProfileHeight <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_profile_height.app_error", nil, "")
}
if o.FileSettings.ProfileWidth <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_profile_width.app_error", nil, "")
}
if o.FileSettings.ThumbnailHeight <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_thumb_height.app_error", nil, "")
}
if o.FileSettings.ThumbnailWidth <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_thumb_width.app_error", nil, "")
}
if len(*o.FileSettings.PublicLinkSalt) < 32 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.file_salt.app_error", nil, "")
}
......
......@@ -452,8 +452,6 @@ func getClientConfig(c *model.Config) map[string]string {
props["EnableFileAttachments"] = strconv.FormatBool(*c.FileSettings.EnableFileAttachments)
props["EnablePublicLink"] = strconv.FormatBool(c.FileSettings.EnablePublicLink)
props["ProfileHeight"] = fmt.Sprintf("%v", c.FileSettings.ProfileHeight)
props["ProfileWidth"] = fmt.Sprintf("%v", c.FileSettings.ProfileWidth)
props["WebsocketPort"] = fmt.Sprintf("%v", *c.ServiceSettings.WebsocketPort)
props["WebsocketSecurePort"] = fmt.Sprintf("%v", *c.ServiceSettings.WebsocketSecurePort)
......
......@@ -529,6 +529,7 @@ export default class AdminSidebar extends React.Component {
}
>
<AdminSidebarSection
key='storage'
name='storage'
title={
<FormattedMessage
......@@ -537,15 +538,6 @@ export default class AdminSidebar extends React.Component {
/>
}
/>
<AdminSidebarSection
name='images'
title={
<FormattedMessage
id='admin.sidebar.images'
defaultMessage='Images'
/>
}
/>
</AdminSidebarSection>
<AdminSidebarSection
name='customization'
......
......@@ -16,7 +16,7 @@ export default class AdminSidebarSection extends React.Component {
type: PropTypes.string,
parentLink: PropTypes.string,
subsection: PropTypes.bool,
children: PropTypes.arrayOf(PropTypes.element),
children: PropTypes.node,
action: PropTypes.node,
onlyActiveOnIndex: PropTypes.bool
};
......@@ -39,7 +39,7 @@ export default class AdminSidebarSection extends React.Component {
const link = this.getLink();
let clonedChildren = null;
if (this.props.children.length > 0) {
if (this.props.children) {
clonedChildren = (
<ul className='nav nav__sub-menu subsections'>
{
......
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import * as Utils from 'utils/utils.jsx';
import AdminSettings from './admin_settings.jsx';
import {FormattedMessage} from 'react-intl';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';
export default class ImageSettings extends AdminSettings {
constructor(props) {
super(props);
this.getConfigFromState = this.getConfigFromState.bind(this);
this.renderSettings = this.renderSettings.bind(this);
}
getConfigFromState(config) {
config.FileSettings.ThumbnailWidth = this.parseInt(this.state.thumbnailWidth);
config.FileSettings.ThumbnailHeight = this.parseInt(this.state.thumbnailHeight);
config.FileSettings.ProfileWidth = this.parseInt(this.state.profileWidth);
config.FileSettings.ProfileHeight = this.parseInt(this.state.profileHeight);
config.FileSettings.PreviewWidth = this.parseInt(this.state.previewWidth);
config.FileSettings.PreviewHeight = this.parseInt(this.state.previewHeight);
return config;
}
getStateFromConfig(config) {
return {
thumbnailWidth: config.FileSettings.ThumbnailWidth,
thumbnailHeight: config.FileSettings.ThumbnailHeight,
profileWidth: config.FileSettings.ProfileWidth,
profileHeight: config.FileSettings.ProfileHeight,
previewWidth: config.FileSettings.PreviewWidth,
previewHeight: config.FileSettings.PreviewHeight
};
}
renderTitle() {
return (
<FormattedMessage
id='admin.files.images'
defaultMessage='Images'
/>
);
}
renderSettings() {
return (
<SettingsGroup>
<TextSetting
id='thumbnailWidth'
label={
<FormattedMessage
id='admin.image.thumbWidthTitle'
defaultMessage='Attachment Thumbnail Width:'
/>
}
placeholder={Utils.localizeMessage('admin.image.thumbWidthExample', 'Ex "120"')}
helpText={
<FormattedMessage
id='admin.image.thumbWidthDescription'
defaultMessage='Width of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.'
/>
}
value={this.state.thumbnailWidth}
onChange={this.handleChange}
/>
<TextSetting
id='thumbnailHeight'
label={
<FormattedMessage
id='admin.image.thumbHeightTitle'
defaultMessage='Attachment Thumbnail Height:'
/>
}
placeholder={Utils.localizeMessage('admin.image.thumbHeightExample', 'Ex "100"')}
helpText={
<FormattedMessage
id='admin.image.thumbHeightDescription'
defaultMessage='Height of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.'
/>
}
value={this.state.thumbnailHeight}
onChange={this.handleChange}
/>
<TextSetting
id='profileWidth'
label={
<FormattedMessage
id='admin.image.profileWidthTitle'
defaultMessage='Profile Picture Width:'
/>
}
placeholder={Utils.localizeMessage('admin.image.profileWidthExample', 'Ex "1024"')}
helpText={
<FormattedMessage
id='admin.image.profileWidthDescription'
defaultMessage='Width of profile picture.'
/>
}
value={this.state.profileWidth}
onChange={this.handleChange}
/>
<TextSetting
id='profileHeight'
label={
<FormattedMessage
id='admin.image.profileHeightTitle'
defaultMessage='Profile Picture Height:'
/>
}
placeholder={Utils.localizeMessage('admin.image.profileHeightExample', 'Ex "0"')}
helpText={
<FormattedMessage
id='admin.image.profileHeightDescription'
defaultMessage='Height of profile picture.'
/>
}
value={this.state.profileHeight}
onChange={this.handleChange}
/>
<TextSetting
id='previewWidth'
label={
<FormattedMessage
id='admin.image.previewWidthTitle'
defaultMessage='Image Preview Width:'
/>
}
placeholder={Utils.localizeMessage('admin.image.previewWidthExample', 'Ex "1024"')}
helpText={
<FormattedMessage
id='admin.image.previewWidthDescription'
defaultMessage='Maximum width of preview image. Updating this value changes how preview images render in future, but does not change images created in the past.'
/>
}
value={this.state.previewWidth}
onChange={this.handleChange}
/>
<TextSetting
id='previewHeight'
label={
<FormattedMessage
id='admin.image.previewHeightTitle'
defaultMessage='Image Preview Height:'
/>
}
placeholder={Utils.localizeMessage('admin.image.previewHeightExample', 'Ex "0"')}
helpText={
<FormattedMessage
id='admin.image.previewHeightDescription'
defaultMessage='Maximum height of preview image ("0": Sets to auto-size). Updating this value changes how preview images render in future, but does not change images created in the past.'
/>
}
value={this.state.previewHeight}
onChange={this.handleChange}
/>
</SettingsGroup>
);
}
}
......@@ -7,9 +7,10 @@ import React, {Component} from 'react';
import {FormattedMessage} from 'react-intl';
import FormError from 'components/form_error.jsx';
import loadingGif from 'images/load.gif';
import Constants from 'utils/constants.jsx';
export default class SettingPicture extends Component {
static propTypes = {
clientError: PropTypes.string,
......@@ -114,8 +115,8 @@ export default class SettingPicture extends Component {
id='setting_picture.help'
defaultMessage='Upload a profile picture in BMP, JPG, JPEG or PNG format, at least {width}px in width and {height}px height.'
values={{
width: global.mm_config.ProfileWidth,
height: global.mm_config.ProfileHeight
width: Constants.PROFILE_WIDTH,
height: Constants.PROFILE_WIDTH
}}
/>
</li>
......
......@@ -415,18 +415,6 @@
"admin.image.maxFileSizeDescription": "Maximum file size for message attachments in megabytes. Caution: Verify server memory can support your setting choice. Large file sizes increase the risk of server crashes and failed uploads due to network interruptions.",
"admin.image.maxFileSizeExample": "50",
"admin.image.maxFileSizeTitle": "Maximum File Size:",
"admin.image.previewHeightDescription": "Maximum height of preview image (\"0\": Sets to auto-size). Updating this value changes how preview images render in future, but does not change images created in the past.",
"admin.image.previewHeightExample": "E.g.: \"0\"",
"admin.image.previewHeightTitle": "Image Preview Height:",
"admin.image.previewWidthDescription": "Maximum width of preview image. Updating this value changes how preview images render in future, but does not change images created in the past.",
"admin.image.previewWidthExample": "E.g.: \"1024\"",
"admin.image.previewWidthTitle": "Image Preview Width:",
"admin.image.profileHeightDescription": "Height of profile picture.",
"admin.image.profileHeightExample": "E.g.: \"0\"",
"admin.image.profileHeightTitle": "Profile Picture Height:",
"admin.image.profileWidthDescription": "Width of profile picture.",
"admin.image.profileWidthExample": "E.g.: \"1024\"",
"admin.image.profileWidthTitle": "Profile Picture Width:",
"admin.image.publicLinkDescription": "32-character salt added to signing of public image links. Randomly generated on install. Click \"Regenerate\" to create new salt.",
"admin.image.publicLinkExample": "E.g.: \"gxHVDcKUyP2y1eiyW8S8na1UYQAfq6J6\"",
"admin.image.publicLinkTitle": "Public Link Salt:",
......@@ -436,12 +424,6 @@
"admin.image.storeDescription": "Storage system where files and image attachments are saved.<br /><br />Selecting \"Amazon S3\" enables fields to enter your Amazon credentials and bucket details.<br /><br />Selecting \"Local File System\" enables the field to specify a local file directory.",
"admin.image.storeLocal": "Local File System",
"admin.image.storeTitle": "File Storage System:",
"admin.image.thumbHeightDescription": "Height of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.",
"admin.image.thumbHeightExample": "E.g.: \"100\"",
"admin.image.thumbHeightTitle": "Attachment Thumbnail Height:",
"admin.image.thumbWidthDescription": "Width of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.",
"admin.image.thumbWidthExample": "E.g.: \"120\"",
"admin.image.thumbWidthTitle": "Attachment Thumbnail Width:",
"admin.integrations.custom": "Custom Integrations",
"admin.integrations.external": "External Services",
"admin.integrations.webrtc": "Mattermost WebRTC",
......@@ -782,7 +764,6 @@
"admin.sidebar.files": "Files",
"admin.sidebar.general": "General",
"admin.sidebar.gitlab": "GitLab",
"admin.sidebar.images": "Images",
"admin.sidebar.integrations": "Integrations",
"admin.sidebar.ldap": "AD/LDAP",
"admin.sidebar.legalAndSupport": "Legal and Support",
......
......@@ -32,7 +32,6 @@ import ExternalServiceSettings from 'components/admin_console/external_service_s
import WebrtcSettings from 'components/admin_console/webrtc_settings.jsx';
import DatabaseSettings from 'components/admin_console/database_settings.jsx';
import StorageSettings from 'components/admin_console/storage_settings.jsx';
import ImageSettings from 'components/admin_console/image_settings.jsx';
import CustomBrandSettings from 'components/admin_console/custom_brand_settings.jsx';
import CustomEmojiSettings from 'components/admin_console/custom_emoji_settings.jsx';
import LinkPreviewsSettings from 'components/admin_console/link_previews_settings.jsx';
......@@ -166,10 +165,6 @@ export default (
path='storage'
component={StorageSettings}
/>
<Route
path='images'
component={ImageSettings}
/>
</Route>
<Route path='customization'>
<IndexRedirect to='custom_brand'/>
......
......@@ -385,6 +385,8 @@ export const Constants = {
MAX_UPLOAD_FILES: 5,
THUMBNAIL_WIDTH: 128,
THUMBNAIL_HEIGHT: 100,
PROFILE_WIDTH: 128,
PROFILE_HEIGHT: 128,
WEB_VIDEO_WIDTH: 640,
WEB_VIDEO_HEIGHT: 480,
MOBILE_VIDEO_WIDTH: 480,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment