mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-06-16 23:00:51 +03:00
Компонент photo
This commit is contained in:
parent
5d21b3c2c4
commit
18bf206a55
|
@ -108,7 +108,7 @@ class ActionSettings extends Action
|
|||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('user_id'))) {
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('target_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$oUser->isAllowEdit()) {
|
||||
|
@ -166,7 +166,7 @@ class ActionSettings extends Action
|
|||
*/
|
||||
$this->Viewer_SetResponseAjax('json');
|
||||
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('user_id'))) {
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('target_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$oUser->isAllowEdit()) {
|
||||
|
@ -245,7 +245,7 @@ class ActionSettings extends Action
|
|||
*/
|
||||
$this->Viewer_SetResponseAjax('json');
|
||||
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('user_id'))) {
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('target_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$oUser->isAllowEdit()) {
|
||||
|
@ -268,7 +268,7 @@ class ActionSettings extends Action
|
|||
{
|
||||
$this->Viewer_SetResponseAjax('json');
|
||||
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('user_id'))) {
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('target_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$oUser->isAllowEdit()) {
|
||||
|
@ -291,7 +291,7 @@ class ActionSettings extends Action
|
|||
{
|
||||
$this->Viewer_SetResponseAjax('json');
|
||||
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('user_id'))) {
|
||||
if (!$oUser = $this->User_GetUserById(getRequestStr('target_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$oUser->isAllowEdit()) {
|
||||
|
|
|
@ -546,6 +546,7 @@ $config['head']['default']['js'] = array(
|
|||
"___path.skin.web___/components/editor/js/editor.js",
|
||||
"___path.skin.web___/components/comment/js/comment.js",
|
||||
"___path.skin.web___/components/comment/js/toolbar.comments.js",
|
||||
"___path.skin.web___/components/photo/js/photo.js",
|
||||
"___path.skin.web___/components/topic/js/topic.js",
|
||||
"___path.skin.web___/components/topic/js/topic-add.js",
|
||||
"___path.skin.web___/components/topic/js/topic-favourite.js",
|
||||
|
@ -572,7 +573,6 @@ $config['head']['default']['js'] = array(
|
|||
"___path.skin.web___/components/user/js/user-follow.js",
|
||||
"___path.skin.web___/components/user/js/user-friend.js",
|
||||
"___path.skin.web___/components/user/js/user-fields.js",
|
||||
"___path.skin.web___/components/user/js/user-photo.js",
|
||||
"___path.skin.web___/components/field/js/field.geo.js",
|
||||
"___path.skin.web___/components/field/js/field.captcha.js",
|
||||
"___path.skin.web___/components/uploader/js/uploader.js",
|
||||
|
@ -633,6 +633,7 @@ $config['head']['default']['css'] = array(
|
|||
"___path.skin.web___/components/comment/css/comment-form.css",
|
||||
"___path.skin.web___/components/comment/css/comment.css",
|
||||
"___path.skin.web___/components/comment/css/toolbar-comments.css",
|
||||
"___path.skin.web___/components/photo/css/photo.css",
|
||||
"___path.skin.web___/components/topic/css/topic.css",
|
||||
"___path.skin.web___/components/wall/css/wall.css",
|
||||
"___path.skin.web___/components/blog/css/blog.css",
|
||||
|
|
|
@ -292,7 +292,7 @@ jQuery(document).ready(function($){
|
|||
$( '.js-user-fields' ).lsUserFields();
|
||||
|
||||
// Фото пользователя
|
||||
$( '.js-user-photo' ).lsUserPhoto({
|
||||
$( '.js-user-photo' ).lsPhoto({
|
||||
urls: {
|
||||
upload: aRouter.settings + 'ajax-upload-photo',
|
||||
remove: aRouter.settings + 'ajax-remove-photo',
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
# Компонент photo
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Фото
|
||||
*
|
||||
* @module ls/photo
|
||||
*
|
||||
* @license GNU General Public License, version 2
|
||||
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
|
||||
* @author Denis Shakhov <denis.shakhov@gmail.com>
|
||||
*/
|
||||
|
||||
.photo {
|
||||
position: relative;
|
||||
min-width: 100%;
|
||||
min-height: 50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Изображение */
|
||||
.photo-image {
|
||||
vertical-align: top;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Действия */
|
||||
.photo-actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: 5px 0;
|
||||
background: rgba( 0, 0, 0, .7 );
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity .3s;
|
||||
transition: opacity .3s;
|
||||
}
|
||||
.photo-actions li {
|
||||
padding: 7px 15px;
|
||||
color: #bbb;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: color .2s;
|
||||
transition: color .2s;
|
||||
}
|
||||
.photo-actions li:hover {
|
||||
color: #eee;
|
||||
}
|
||||
.photo:hover .photo-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* @modifier nophoto */
|
||||
.photo--nophoto .photo-image {
|
||||
width: 100%;
|
||||
}
|
||||
.photo--nophoto .photo-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
.photo--nophoto .photo-actions-crop-avatar,
|
||||
.photo--nophoto .photo-actions-remove {
|
||||
display: none;
|
||||
}
|
223
application/frontend/skin/developer/components/photo/js/photo.js
Normal file
223
application/frontend/skin/developer/components/photo/js/photo.js
Normal file
|
@ -0,0 +1,223 @@
|
|||
/**
|
||||
* Photo
|
||||
*
|
||||
* @module ls/photo
|
||||
*
|
||||
* @license GNU General Public License, version 2
|
||||
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
|
||||
* @author Denis Shakhov <denis.shakhov@gmail.com>
|
||||
*
|
||||
* TODO: Вынести опции кропа для фото и аватары в общие опции
|
||||
* TODO: Сделать использование кропа аватара опциональным
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
$.widget( "livestreet.lsPhoto", {
|
||||
/**
|
||||
* Дефолтные опции
|
||||
*/
|
||||
options: {
|
||||
// Ссылки
|
||||
urls: {
|
||||
upload: null,
|
||||
remove: null,
|
||||
crop_photo: null,
|
||||
crop_avatar: null,
|
||||
save_photo: null,
|
||||
save_avatar: null,
|
||||
cancel_photo: null,
|
||||
},
|
||||
// Селекторы
|
||||
selectors: {
|
||||
image: '.js-photo-image',
|
||||
actions: {
|
||||
upload: '.js-photo-actions-upload',
|
||||
upload_label: '.js-photo-actions-upload-label',
|
||||
upload_input: '.js-photo-actions-upload-input',
|
||||
crop_avatar: '.js-photo-actions-crop-avatar',
|
||||
remove: '.js-photo-actions-remove',
|
||||
},
|
||||
},
|
||||
// Классы
|
||||
classes: {
|
||||
nophoto: 'photo--nophoto'
|
||||
},
|
||||
// Параметры передаваемые в аякс запросах
|
||||
params: {}
|
||||
|
||||
// Изменение аватара
|
||||
// changeavatar: function() {}
|
||||
},
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
_create: function () {
|
||||
var _this = this;
|
||||
|
||||
this.option( 'params.target_id', this.element.data( 'target-id' ) );
|
||||
|
||||
this.elements = {
|
||||
image: this.element.find( this.option( 'selectors.image' ) ),
|
||||
actions: {
|
||||
upload: this.element.find( this.option( 'selectors.actions.upload' ) ),
|
||||
upload_label: this.element.find( this.option( 'selectors.actions.upload_label' ) ),
|
||||
upload_input: this.element.find( this.option( 'selectors.actions.upload_input' ) ),
|
||||
crop_avatar: this.element.find( this.option( 'selectors.actions.crop_avatar' ) ),
|
||||
remove: this.element.find( this.option( 'selectors.actions.remove' ) ),
|
||||
}
|
||||
};
|
||||
|
||||
this.elements.actions.upload_input.on( 'change' + this.eventNamespace, function () {
|
||||
_this.upload( $( this ) );
|
||||
});
|
||||
|
||||
this.elements.actions.crop_avatar.on( 'click' + this.eventNamespace, this.cropAvatar.bind( this ) );
|
||||
this.elements.actions.remove.on( 'click' + this.eventNamespace, this.remove.bind( this ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Удаление фото
|
||||
*/
|
||||
remove: function() {
|
||||
ls.ajax.load( this.option( 'urls.remove' ), this.option( 'params' ), function( response ) {
|
||||
if ( response.bStateError ) {
|
||||
ls.msg.error( null, response.sMsg );
|
||||
} else {
|
||||
this.element.addClass( this.option( 'classes.nophoto' ) );
|
||||
this.elements.image.attr( 'src', response.photo );
|
||||
this.elements.actions.upload_label.text( response.upload_text );
|
||||
|
||||
this._trigger( 'changeavatar', null, [ this, response.avatars ] );
|
||||
}
|
||||
}.bind( this ));
|
||||
},
|
||||
|
||||
/**
|
||||
* Загрузка фото
|
||||
*/
|
||||
upload: function( input ) {
|
||||
var form = $( '<form method="post" enctype="multipart/form-data"></form>' ).hide().appendTo( 'body' );
|
||||
input.clone( true ).insertAfter( input );
|
||||
input.appendTo( form );
|
||||
$( '<input type="hidden" name="target_id" value="' + this.option( 'params.target_id' ) + '" >').appendTo( form );
|
||||
|
||||
ls.ajax.submit( this.option( 'urls.upload' ), form, function ( response ) {
|
||||
if ( response.bStateError ) {
|
||||
ls.msg.error( response.sMsgTitle, response.sMsg );
|
||||
} else {
|
||||
this.cropPhoto( response );
|
||||
}
|
||||
|
||||
form.remove();
|
||||
}.bind( this ));
|
||||
},
|
||||
|
||||
/**
|
||||
* Показывает модальное кропа фото
|
||||
*/
|
||||
cropPhoto: function( image ) {
|
||||
this.showModal( image, false, {
|
||||
crop_params : {
|
||||
minSize: [ 370, 370 ]
|
||||
},
|
||||
save_params : this.option( 'params' ),
|
||||
crop_url : this.option( 'urls.crop_photo' ),
|
||||
save_url : this.option( 'urls.save_photo' ),
|
||||
save_callback : function( response, modal, image ) {
|
||||
this.element.removeClass( this.option( 'classes.nophoto' ) );
|
||||
this.elements.image.attr( 'src', response.photo );
|
||||
this.elements.actions.upload_label.text( response.upload_text );
|
||||
|
||||
// TODO: Временный хак (модальное не показывается сразу после закрытия предыдущего окна)
|
||||
setTimeout( this.cropAvatar.bind( this ), 300);
|
||||
},
|
||||
modal_close_callback : function( event, modal ) {
|
||||
ls.ajax.load( this.option( 'urls.cancel_photo' ), this.option( 'params' ) );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Показывает модальное кропа аватара
|
||||
*/
|
||||
cropAvatar: function() {
|
||||
var photo = this.elements.image;
|
||||
var image = {
|
||||
path: photo.attr( 'src' ),
|
||||
// TODO: IE8 naturalWidth naturalHeight
|
||||
original_width: photo[0].naturalWidth,
|
||||
original_height: photo[0].naturalHeight,
|
||||
width: photo[0].naturalWidth,
|
||||
height: photo[0].naturalHeight
|
||||
};
|
||||
|
||||
this.showModal( image, true, {
|
||||
crop_params : {
|
||||
minSize: [ 100, 100 ],
|
||||
aspectRatio: 1
|
||||
},
|
||||
save_callback : function( response, modal, image ) {
|
||||
this._trigger( 'changeavatar', null, [ this, response.avatars ] );
|
||||
},
|
||||
save_params : this.option( 'params' ),
|
||||
crop_url : this.option( 'urls.crop_avatar' ),
|
||||
save_url : this.option( 'urls.save_avatar' )
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Показывает модальное кропа
|
||||
*
|
||||
* TODO: Перенести в компонент crop
|
||||
*/
|
||||
showModal: function( image, usePreview, params ) {
|
||||
var _this = this;
|
||||
|
||||
ls.modal.load( params.crop_url, {
|
||||
original_width: image.original_width,
|
||||
original_height: image.original_height,
|
||||
width: image.width,
|
||||
height: image.height,
|
||||
image_src: image.path,
|
||||
use_preview: usePreview
|
||||
}, {
|
||||
aftershow: function( e, modal ) {
|
||||
var crop = modal.element.find('.js-crop').lsCrop( params.crop_params );
|
||||
var submit = modal.element.find('.js-crop-submit');
|
||||
var image = crop.lsCrop( 'getImage' );
|
||||
|
||||
submit.on( 'click', function() {
|
||||
var paramsRequest = $.extend({}, {
|
||||
size: crop.lsCrop( 'getSelection' ),
|
||||
canvas_width: image.innerWidth()
|
||||
}, params.save_params || {});
|
||||
|
||||
ls.ajax.load( params.save_url, paramsRequest, function( response ) {
|
||||
if ( response.bStateError ) {
|
||||
ls.msg.error( null, response.sMsg );
|
||||
} else {
|
||||
modal.hide();
|
||||
|
||||
if ( $.isFunction( params.save_callback ) ) {
|
||||
params.save_callback.call( _this, response, modal, image );
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
afterhide: function( event, modal ) {
|
||||
if ( $.isFunction( params.modal_close_callback ) ) {
|
||||
params.modal_close_callback.call( _this, event, modal );
|
||||
}
|
||||
},
|
||||
center: false
|
||||
});
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,60 @@
|
|||
{**
|
||||
* Photo
|
||||
*
|
||||
* @param string $url
|
||||
* @param integer $targetId
|
||||
* @param boolean $hasPhoto
|
||||
* @param boolean $photoPath
|
||||
* @param boolean $photoAltText
|
||||
* @param boolean $editable
|
||||
*
|
||||
* TODO: Вынести текстовки в photo
|
||||
*}
|
||||
|
||||
{$component = 'photo'}
|
||||
|
||||
{$hasPhoto = $smarty.local.hasPhoto}
|
||||
{$mods = $smarty.local.mods}
|
||||
|
||||
{if ! $hasPhoto}
|
||||
{$mods = "$mods nophoto"}
|
||||
{/if}
|
||||
|
||||
<div class="{$component} {mod name=$component mods=$mods} {$smarty.local.classes}"
|
||||
data-target-id="{$smarty.local.targetId}"
|
||||
{foreach $smarty.local.attributes as $attr}{$attr@key}="{$attr@value}" {/foreach}>
|
||||
|
||||
{* Фото *}
|
||||
<a href="{$smarty.local.url}">
|
||||
<img src="{$smarty.local.photoPath}" alt="{$smarty.local.photoAltText}" class="{$component}-image js-photo-image" />
|
||||
</a>
|
||||
|
||||
{* Действия *}
|
||||
{if $smarty.local.editable}
|
||||
<ul class="{$component}-actions">
|
||||
{* Загрузить *}
|
||||
<li class="{$component}-actions-upload js-photo-actions-upload">
|
||||
<label class="form-input-file">
|
||||
<span class="js-photo-actions-upload-label">
|
||||
{if $hasPhoto}
|
||||
{lang 'user.photo.actions.change_photo'}
|
||||
{else}
|
||||
{lang 'user.photo.actions.upload_photo'}
|
||||
{/if}
|
||||
</span>
|
||||
<input type="file" name="photo" class="js-photo-actions-upload-input">
|
||||
</label>
|
||||
</li>
|
||||
|
||||
{* Изменить аватар *}
|
||||
<li class="{$component}-actions-crop-avatar js-photo-actions-crop-avatar">
|
||||
{lang 'user.photo.actions.change_avatar'}
|
||||
</li>
|
||||
|
||||
{* Удалить фото *}
|
||||
<li class="{$component}-actions-remove js-photo-actions-remove">
|
||||
{lang 'user.photo.actions.remove'}
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
|
@ -10,51 +10,29 @@
|
|||
{/block}
|
||||
|
||||
{block 'block_content'}
|
||||
<div class="user-photo {if ! $oUserProfile->getProfileFoto()}user-photo--nophoto{/if} js-user-photo" data-user-id="{$oUserProfile->getId()}">
|
||||
{* Статус онлайн\оффлайн *}
|
||||
{if $oSession}
|
||||
{if $oUserProfile->isOnline() && $smarty.now - strtotime($oSession->getDateLast()) < 60*5}
|
||||
<div class="user-status user-status--online">{$aLang.user.status.online}</div>
|
||||
{else}
|
||||
<div class="user-status user-status--offline">
|
||||
{$date = {date_format date=$oSession->getDateLast() hours_back="12" minutes_back="60" day_back="8" now="60*5" day="day H:i" format="j F в G:i"}}
|
||||
{* Статус онлайн\оффлайн *}
|
||||
{if $oSession}
|
||||
{if $oUserProfile->isOnline() && $smarty.now - strtotime($oSession->getDateLast()) < 60*5}
|
||||
<div class="user-status user-status--online">{$aLang.user.status.online}</div>
|
||||
{else}
|
||||
<div class="user-status user-status--offline">
|
||||
{$date = {date_format date=$oSession->getDateLast() hours_back="12" minutes_back="60" day_back="8" now="60*5" day="day H:i" format="j F в G:i"}|lower}
|
||||
|
||||
{if $oUserProfile->getProfileSex() != 'woman'}
|
||||
{lang 'user.status.was_online_male' date=$date}
|
||||
{else}
|
||||
{lang 'user.status.was_online_female' date=$date}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{if $oUserProfile->getProfileSex() != 'woman'}
|
||||
{lang 'user.status.was_online_male' date=$date}
|
||||
{else}
|
||||
{lang 'user.status.was_online_female' date=$date}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{* Фото *}
|
||||
<a href="{$oUserProfile->getUserWebPath()}">
|
||||
<img src="{$oUserProfile->getProfileFotoPath()}" alt="{$oUserProfile->getDisplayName()} photo" class="user-photo-image js-user-photo-image" />
|
||||
</a>
|
||||
|
||||
{* Действия (редактировать/удалить) *}
|
||||
{if $oUserProfile->isAllowEdit()}
|
||||
<ul class="user-photo-actions">
|
||||
<li class="js-user-photo-actions-upload">
|
||||
<label class="form-input-file">
|
||||
<span class="js-user-photo-actions-upload-label">
|
||||
{if $oUserProfile->getProfileFoto()}
|
||||
{lang 'user.photo.actions.change_photo'}
|
||||
{else}
|
||||
{lang 'user.photo.actions.upload_photo'}
|
||||
{/if}
|
||||
</span>
|
||||
<input type="file" name="photo" class="js-user-photo-actions-upload-input">
|
||||
</label>
|
||||
</li>
|
||||
<li class="js-user-photo-actions-crop-avatar" style="{if !$oUserProfile->getProfileFoto()}display:none;{/if}">
|
||||
{lang 'user.photo.actions.change_avatar'}
|
||||
</li>
|
||||
<li class="js-user-photo-actions-remove" style="{if !$oUserProfile->getProfileFoto()}display:none;{/if}">
|
||||
{lang 'user.photo.actions.remove'}
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{include 'components/photo/photo.tpl'
|
||||
classes = 'js-user-photo'
|
||||
hasPhoto = $oUserProfile->getProfileFoto()
|
||||
editable = $oUserProfile->isAllowEdit()
|
||||
targetId = $oUserProfile->getId()
|
||||
url = $oUserProfile->getUserWebPath()
|
||||
photoPath = $oUserProfile->getProfileFotoPath()
|
||||
photoAltText = $oUserProfile->getDisplayName()}
|
||||
{/block}
|
|
@ -6,16 +6,7 @@
|
|||
*/
|
||||
.block--user-photo .block-content {
|
||||
padding: 0;
|
||||
}
|
||||
.user-photo {
|
||||
position: relative;
|
||||
min-width: 100%;
|
||||
min-height: 50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-photo-image {
|
||||
vertical-align: top;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Статус (онлайн/оффлайн) */
|
||||
|
@ -23,6 +14,7 @@
|
|||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
padding: 12px 15px;
|
||||
font: 300 13px/1em 'Open Sans';
|
||||
}
|
||||
|
@ -37,41 +29,6 @@
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
/* Действия */
|
||||
.user-photo-actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: 5px 0;
|
||||
background: rgba( 0, 0, 0, .7 );
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity .3s;
|
||||
transition: opacity .3s;
|
||||
}
|
||||
.user-photo-actions li {
|
||||
padding: 7px 15px;
|
||||
color: #bbb;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: color .2s;
|
||||
transition: color .2s;
|
||||
}
|
||||
.user-photo-actions li:hover {
|
||||
color: #eee;
|
||||
}
|
||||
.user-photo:hover .user-photo-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* @modifier nophoto */
|
||||
.user-photo--nophoto .user-photo-image {
|
||||
width: 100%;
|
||||
}
|
||||
.user-photo--nophoto .user-photo-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Блок управления на странице пользователя
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue