diff --git a/QvitterPlugin.php b/QvitterPlugin.php index 2830352..89b930e 100644 --- a/QvitterPlugin.php +++ b/QvitterPlugin.php @@ -195,8 +195,8 @@ class QvitterPlugin extends Plugin { $m->connect('api/qvitter/allfollowing/:id.json', array('action' => 'apiqvitterallfollowing', 'id' => Nickname::INPUT_FMT)); - $m->connect('api/qvitter/update_cover_photo.json', - array('action' => 'ApiUpdateCoverPhoto')); + $m->connect('api/account/update_profile_banner.json', + array('action' => 'ApiAccountUpdateProfileBanner')); $m->connect('api/qvitter/update_background_image.json', array('action' => 'ApiUpdateBackgroundImage')); $m->connect('api/qvitter/update_avatar.json', diff --git a/actions/apiupdatecoverphoto.php b/actions/apiaccountupdateprofilebanner.php similarity index 56% rename from actions/apiupdatecoverphoto.php rename to actions/apiaccountupdateprofilebanner.php index 6f9b4fb..4f07dcb 100644 --- a/actions/apiupdatecoverphoto.php +++ b/actions/apiaccountupdateprofilebanner.php @@ -1,7 +1,7 @@ user = $this->auth_user; - $this->cropW = $this->trimmed('cropW'); - $this->cropH = $this->trimmed('cropH'); - $this->cropX = $this->trimmed('cropX'); - $this->cropY = $this->trimmed('cropY'); - $this->img = $this->trimmed('img'); + $this->cropW = $this->trimmed('width'); + $this->cropH = $this->trimmed('height'); + $this->cropX = $this->trimmed('offset_left'); + $this->cropY = $this->trimmed('offset_top'); + $this->img = $this->trimmed('banner'); return true; } @@ -76,33 +76,75 @@ class ApiUpdateCoverPhotoAction extends ApiAuthAction protected function handle() { parent::handle(); + $profile = $this->user->getProfile(); - $profile = $this->user->getProfile(); - $base64img = $this->img; - if(stristr($base64img, 'image/jpeg')) { - $base64img_mime = 'image/jpeg'; - } - elseif(stristr($base64img, 'image/png')) { - // should convert to jpg here!! - $base64img_mime = 'image/png'; - } - $base64img = str_replace('data:image/jpeg;base64,', '', $base64img); - $base64img = str_replace('data:image/png;base64,', '', $base64img); - $base64img = str_replace(' ', '+', $base64img); - $base64img_hash = md5($base64img); - $base64img = base64_decode($base64img); - $base64img_basename = basename('cover'); - $base64img_filename = File::filename($profile, $base64img_basename, $base64img_mime); - $base64img_path = File::path($base64img_filename); - $base64img_success = file_put_contents($base64img_path, $base64img); - $base64img_mimetype = MediaFile::getUploadedMimeType($base64img_path, $base64img_filename); - $mediafile = new MediaFile($profile, $base64img_filename, $base64img_mimetype); - $imagefile = new ImageFile($mediafile->fileRecord->id, File::path($mediafile->filename)); - $imagefile->resizeTo(File::path($mediafile->filename), array('width'=>$this->cropW, 'height'=>$this->cropH, 'x'=>$this->cropX, 'y'=>$this->cropY, 'w'=>$this->cropW, 'h'=>$this->cropH)); - $result['url'] = File::url($mediafile->filename); + // see if we have regular uploaded image data + try { - Profile_prefs::setData($profile, 'qvitter', 'cover_photo', $result['url']); + $mediafile = MediaFile::fromUpload('banner', $profile); + } catch (NoUploadedMediaException $e) { + + // if not we may have base64 data + $img = $this->img; + if(stristr($img, 'image/jpeg')) { + $img_mime = 'image/jpeg'; + } + elseif(stristr($img, 'image/png')) { + // should convert to jpg here!! + $img_mime = 'image/png'; + } + + // i don't remember why we had to do this + $img = str_replace('data:image/jpeg;base64,', '', $img); + $img = str_replace('data:image/png;base64,', '', $img); + $img = str_replace(' ', '+', $img); + $img = base64_decode($img, true); + + try { + $img_filename = File::filename($profile, 'cover', $img_mime); + $img_path = File::path($img_filename); + $img_success = file_put_contents($img_path, $img); + $img_mimetype = MediaFile::getUploadedMimeType($img_path, $img_filename); + $mediafile = new MediaFile($profile, $img_filename, $img_mimetype); + } catch (Exception $e) { + $this->clientError($e, 400); + } + } + + if(!$mediafile instanceof MediaFile) { + $this->clientError(_('Could not process image data.'), 400); + } + + // maybe resize + $width = $this->cropW; + $height = $this->cropH; + $scale = 1; + if($width > 1200) { + $scale = 1200/$width; + } elseif($height > 600) { + $scale = 600/$height; + } + $width = round($width*$scale); + $height = round($height*$scale); + + // crop + try { + $imagefile = new ImageFile($mediafile->fileRecord->id, File::path($mediafile->filename)); + $imagefile->resizeTo(File::path($mediafile->filename), array('width'=>$width, 'height'=>$height, 'x'=>$this->cropX, 'y'=>$this->cropY, 'w'=>$this->cropW, 'h'=>$this->cropH)); + $result['url'] = File::url($mediafile->filename); + } catch (Exception $e) { + $this->clientError(_('The image could not be resized and cropped. '.$e), 422); + } + + // save in profile_prefs + try { + Profile_prefs::setData($profile, 'qvitter', 'cover_photo', $result['url']); + } catch (ServerException $e) { + $this->clientError(_('The image could not be resized and cropped. '.$e), 422); + } + + // return json $this->initDocument('json'); $this->showJsonObjects($result); $this->endDocument('json'); diff --git a/css/qvitter.css b/css/qvitter.css index 6664bfb..d9db0a5 100644 --- a/css/qvitter.css +++ b/css/qvitter.css @@ -5687,7 +5687,7 @@ body.rtl #feed-header-inner h2 { } .modal-draggable { - width:95%; + width:100%; } diff --git a/js/dom-functions.js b/js/dom-functions.js index 2d2d538..091ccb0 100644 --- a/js/dom-functions.js +++ b/js/dom-functions.js @@ -657,6 +657,11 @@ function setNewCurrentStream(streamObject,setLocation,fallbackId,actionOnSuccess weAreReloading = true; } + // show hidden items when we reload + if(weAreReloading) { + $('#feed-body').children('.stream-item').removeClass('hidden'); + } + // remember the most recent stream object window.currentStreamObject = streamObject; @@ -2256,8 +2261,10 @@ function buildAttachmentHTML(attachments){ && this.oembed.type != 'photo') { var oembedImage = ''; - // not if stripped from html it's the same as the title (wordpress does this..) - if(typeof this.thumb_url != 'undefined' && this.thumb_url !== null) { + // only local images + if(typeof this.thumb_url != 'undefined' + && this.thumb_url !== null + && isLocalURL(this.thumb_url)) { oembedImage = '
'; } diff --git a/js/qvitter.js b/js/qvitter.js index d5e73ff..fc85c12 100644 --- a/js/qvitter.js +++ b/js/qvitter.js @@ -165,6 +165,15 @@ $('body').on({ tooltip_data = $(e.target).closest('.queet').find('.thumb-container[href="' + $(e.target).attr('data-tooltip') + '"]').outerHTML(); tooltipClass = 'thumb'; } + // sometimes the attachment link in the queet text does not give us any clue to + // which attachment it is referring to. but if it is the only link and there is + // exactly one attachment, we can safely assume that the link is referring to + // that attachment + else if($(e.target).closest('.queet').find('.thumb-container').length == 1 + && $(e.target).closest('.queet-text').find('a.attachment').length == 1) { + tooltip_data = $(e.target).closest('.queet').find('.thumb-container').outerHTML(); + tooltipClass = 'thumb'; + } } else if($('#feed-body').hasClass('quotes-hidden-by-user') && !$(e.target).is('.quote-link-container') @@ -2461,13 +2470,13 @@ $('body').on('click','.action-reply-container',function(){ var queetHtmlWithoutFooter = $queetHtml.html(); popUpAction('popup-reply-' + this_stream_item_id, window.sL.replyTo + ' ' + this_stream_item.children('.queet').find('.screen-name').html(),replyFormHtml(this_stream_item,this_stream_item_id),queetHtmlWithoutFooter); + $('#popup-reply-' + this_stream_item_id).find('.modal-body').find('.queet-box').trigger('click'); // expand + // fix the width of the queet box, otherwise the syntax highlighting break var queetBox = $('#popup-reply-' + this_stream_item_id).find('.modal-body').find('.inline-reply-queetbox'); var queetBoxWidth = queetBox.width()-20; queetBox.children('.queet-box-syntax, .syntax-middle, .syntax-two').width(queetBoxWidth); - $('#popup-reply-' + this_stream_item_id).find('.modal-body').find('.queet-box').trigger('click'); // expand - maybePrefillQueetBoxWithCachedText(queetBox.children('.queet-box')); }); @@ -3582,17 +3591,29 @@ $('body').on('click','.crop-and-save-button',function(){ // if this is the cover photo if($('#edit-profile-popup .jwc_frame.cover-photo-to-crop').length>0) { - $.ajax({ url: window.apiRoot + 'qvitter/update_cover_photo.json', - type: "POST", - data: { - cropH: window.jwc.result.cropH, - cropW: window.jwc.result.cropW, - cropX: window.jwc.result.cropX, - cropY: window.jwc.result.cropY, - img: $('#cover-photo-to-crop').attr('src') + + var coverImgFormData = new FormData(); + coverImgFormData.append('banner', $('#cover-photo-input')[0].files[0]); + coverImgFormData.append('height', window.jwc.result.cropH); + coverImgFormData.append('width', window.jwc.result.cropW); + coverImgFormData.append('offset_left', window.jwc.result.cropX); + coverImgFormData.append('offset_top', window.jwc.result.cropY); + + $.ajax({ + url: window.apiRoot + 'account/update_profile_banner.json', + type: "POST", + data: coverImgFormData, + processData: false, + contentType: false, + cache: false, + dataType: "json", + error: function(data){ + console.log('error saving profile banner'); console.log(data); + $('.crop-and-save-button').removeAttr('disabled'); + $('.crop-and-save-button').removeClass('disabled'); + cleanUpAfterCropping(); + remove_spinner(); }, - dataType:"json", - error: function(data){ console.log('error'); console.log(data); }, success: function(data) { remove_spinner(); if(typeof data.error == 'undefined') { @@ -3744,8 +3765,6 @@ function coverPhotoAndAvatarSelectAndCrop(e, coverOrAvatar) { if(coverOrAvatar == 'upload-cover-photo') { var targetWidth = 588; var targetHeight = 260; - var maxWidth = 1040; - var minWidth = 1040; var cropId = 'cover-photo-to-crop'; } else if(coverOrAvatar == 'upload-avatar') {