mirror of
https://github.com/humhub/humhub.git
synced 2025-01-17 22:28:51 +01:00
Integration of mentioning for posts
This commit is contained in:
parent
a11769d0e5
commit
f38bc6ff6e
75
css/mention.css
Normal file
75
css/mention.css
Normal file
@ -0,0 +1,75 @@
|
||||
body {
|
||||
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 400px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
hyphens: auto;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
white-space: pre-wrap;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mention-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mention-html-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mention-overlay {
|
||||
/*opacity: 0.5;*/
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
-ms-word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.mention-overlay span {
|
||||
background-color: #dae4f7;
|
||||
/* border: 2px solid blue;
|
||||
border-radius: 2px;*/
|
||||
color: #dae4f7;
|
||||
padding: 0px 0 2px 0;
|
||||
/* border: 1px solid #a4bbec;
|
||||
border-radius: 3px;
|
||||
|
||||
background: #dae4f7; *//* Old browsers *//*
|
||||
*//* IE9 SVG, needs conditional override of 'filter' to 'none' *//*
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RhZTRmNyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiZWNmZjMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
|
||||
background: -moz-linear-gradient(top, #dae4f7 0%, #becff3 100%); *//* FF3.6+ *//*
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dae4f7), color-stop(100%,#becff3)); *//* Chrome,Safari4+ *//*
|
||||
background: -webkit-linear-gradient(top, #dae4f7 0%,#becff3 100%); *//* Chrome10+,Safari5.1+ *//*
|
||||
background: -o-linear-gradient(top, #dae4f7 0%,#becff3 100%); *//* Opera 11.10+ *//*
|
||||
background: -ms-linear-gradient(top, #dae4f7 0%,#becff3 100%); *//* IE10+ *//*
|
||||
background: linear-gradient(to bottom, #dae4f7 0%,#becff3 100%); *//* W3C *//*
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dae4f7', endColorstr='#becff3',GradientType=0 ); *//* IE6-8 */
|
||||
|
||||
/*border: 1px solid #d6e1e9;*/
|
||||
border-radius: 3px;
|
||||
background-color: #d6e1e9;
|
||||
|
||||
}
|
||||
|
||||
.mention-userlist {
|
||||
display: none;
|
||||
position: fixed;
|
||||
}
|
@ -44,6 +44,9 @@ hr {
|
||||
.col-md-12 {
|
||||
position: inherit;
|
||||
}
|
||||
textarea {
|
||||
height: 1.5em;
|
||||
}
|
||||
.topbar {
|
||||
position: fixed;
|
||||
display: block;
|
||||
|
@ -54,6 +54,10 @@ hr {
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height:1.5em;
|
||||
}
|
||||
|
||||
//
|
||||
// 2) Topbar
|
||||
// --------------------------------------------------
|
||||
|
437
js/jquery.mention.js
Normal file
437
js/jquery.mention.js
Normal file
@ -0,0 +1,437 @@
|
||||
$.fn.mention = function (options) {
|
||||
|
||||
var opts = $.extend({}, $.fn.mention.defaults, options);
|
||||
|
||||
|
||||
var mq = window.matchMedia("(min-width: 1023px)");
|
||||
|
||||
if (mq.matches) {
|
||||
// window width is at least 500px
|
||||
|
||||
|
||||
// variable for userlist arrow navigation
|
||||
var chosen = "";
|
||||
|
||||
// variables for text selection (username replacement)
|
||||
var searchStart = 0;
|
||||
var searchEnd = 0;
|
||||
|
||||
$(this).each(function () {
|
||||
|
||||
// create container arround textarea
|
||||
$(this).wrap('<div class="mention-container" style="height: 36px"></div>');
|
||||
|
||||
// add mention overlay
|
||||
$(this).before('<div class="mention-overlay"></div>');
|
||||
|
||||
// textarea for html content
|
||||
$(this).before('<textarea class="mention-html-content" name=""></textarea>');
|
||||
|
||||
// add dropdown list for user results
|
||||
$(this).parent().append('<ul class="dropdown-menu mention-userlist" role="menu" aria-labelledby="dropdownMenu"><li><div class="loader"></div></li></ul>');
|
||||
|
||||
// set the css properties from textarea to mention overlay
|
||||
$(this).parent().find('.mention-overlay').css({
|
||||
/*width: $textarea.css('width'),*/
|
||||
fontFamily: opts.fontFamily,
|
||||
fontWeight: opts.fontWeight,
|
||||
fontSize: opts.fontSize,
|
||||
border: opts.border,
|
||||
color: opts.color,
|
||||
padding: opts.padding,
|
||||
minHeight: opts.minHeight,
|
||||
lineHeight: opts.lineHeight,
|
||||
borderRadius: opts.borderRadius
|
||||
|
||||
});
|
||||
|
||||
// change textarea style
|
||||
$(this).css({
|
||||
position: 'absolute',
|
||||
resize: 'none',
|
||||
//height: '36px',
|
||||
backgroundColor: 'transparent'
|
||||
|
||||
})
|
||||
|
||||
// set name of original textarea to the new generated one
|
||||
$(this).parent().find('.mention-html-content').attr('name', $(this).attr('name'));
|
||||
|
||||
// clear name for original textarea
|
||||
$(this).attr('name', '');
|
||||
|
||||
//
|
||||
// Event for handle user input
|
||||
//
|
||||
$(this).keydown(function (event) {
|
||||
|
||||
if (event.keyCode == 40 || event.keyCode == 38 || event.keyCode == 13 || event.keyCode == 9) {
|
||||
|
||||
// disable default behavior for arrow, enter and tab keys, when userlist is open
|
||||
if ($.fn.mention.defaults.stateUserList == true) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
}
|
||||
// update mention overlay
|
||||
$.fn.mention.updateMentionOverlay($(this));
|
||||
|
||||
})
|
||||
|
||||
$(window).scroll(function () {
|
||||
|
||||
// hide userlist
|
||||
$('.mention-userlist').hide();
|
||||
|
||||
})
|
||||
|
||||
// set textarea height to mention container
|
||||
$(this).on('change keyup paste', function () {
|
||||
$.fn.mention.updateMentionContainerSize($(this));
|
||||
})
|
||||
|
||||
|
||||
$(this).keyup(function (event) {
|
||||
|
||||
// check if a @ char exists
|
||||
if ($(this).val().search(" @") == -1) {
|
||||
|
||||
// set userlist state to "close" if no @ char was found to deactivate the search
|
||||
$.fn.mention.defaults.stateUserList = false;
|
||||
|
||||
}
|
||||
|
||||
// catch input from @ char for windows or mac
|
||||
if (event.altKey && event.keyCode == 76 || event.keyCode == 81) {
|
||||
|
||||
// check if there an space before @ to ignore email inputs
|
||||
if ($(this).val().search(" @") != -1) {
|
||||
|
||||
// save the current cursor position
|
||||
searchStart = $(this).textrange('get').start;
|
||||
|
||||
// set mention userlist to the right position
|
||||
$.fn.mention.setPosition($(this));
|
||||
|
||||
// set userlist state to "open"
|
||||
$.fn.mention.defaults.stateUserList = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// find userlist element
|
||||
var _obj = $(this).parent().find('.mention-userlist');
|
||||
|
||||
// navigate with arrow keys
|
||||
if (event.keyCode == 40) {
|
||||
|
||||
// select next <li> element
|
||||
if (chosen === "") {
|
||||
chosen = 1;
|
||||
} else if ((chosen + 1) < _obj.find('li').length) {
|
||||
chosen++;
|
||||
}
|
||||
_obj.find('li').removeClass('selected');
|
||||
_obj.find('li:eq(' + chosen + ')').addClass('selected');
|
||||
return false;
|
||||
|
||||
// navigate with arrow keys
|
||||
} else if (event.keyCode == 38) {
|
||||
|
||||
// select previous <li> element
|
||||
if (chosen === "") {
|
||||
chosen = 1;
|
||||
} else if (chosen > 0) {
|
||||
chosen--;
|
||||
}
|
||||
_obj.find('li').removeClass('selected');
|
||||
_obj.find('li:eq(' + chosen + ')').addClass('selected');
|
||||
return false;
|
||||
|
||||
} else if (event.keyCode == 13 || event.keyCode == 9) {
|
||||
|
||||
// simulate click event
|
||||
if ($.fn.mention.defaults.stateUserList == true) {
|
||||
window.location.href = _obj.find('.selected').children('a').attr('href');
|
||||
}
|
||||
|
||||
} else if ($.fn.mention.defaults.stateUserList == true) {
|
||||
|
||||
// set mention userlist to the right position
|
||||
$.fn.mention.setPosition($(this));
|
||||
|
||||
// safe the current cursor position
|
||||
searchEnd = $(this).textrange('get').start;
|
||||
|
||||
// select text from entered @ char until current cursor position
|
||||
$(this).textrange('set', searchStart, searchEnd - searchStart);
|
||||
|
||||
// save selection
|
||||
var _str = $(this).textrange('get');
|
||||
|
||||
if (_str.length >= 1) {
|
||||
|
||||
// search for user by string
|
||||
loadUser($(this), _str.text);
|
||||
} else {
|
||||
$(this).parent().find('.mention-userlist').hide();
|
||||
}
|
||||
|
||||
// set cursor the back to the last position
|
||||
$(this).textrange('set', searchEnd, 0);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
//
|
||||
// Update the original textarea by losing focus
|
||||
//
|
||||
$(this).focusout(function () {
|
||||
|
||||
// the focusout event will be also fired by clicking an userlist entry with mouse
|
||||
// so check, if the user selection is over, before updating the original textarea
|
||||
if ($.fn.mention.defaults.stateUserList == false) {
|
||||
|
||||
// hide mention userlist
|
||||
$(this).parent().find('.mention-userlist').hide();
|
||||
|
||||
// save mention overlay object
|
||||
var $element = $(this).parent().find('.mention-overlay');
|
||||
|
||||
// save unchanged content
|
||||
var _html = $element.html();
|
||||
|
||||
// change <span> tags with just the user guids
|
||||
for (var i = 0; i <= $element.html().split('</span>').length; i++) {
|
||||
var _guid = $element.children('span').attr('data-guid');
|
||||
$element.children('span').first().replaceWith('@' + _guid);
|
||||
}
|
||||
|
||||
// add modified content to the original textarea
|
||||
$(this).parent().find('.mention-html-content').val($element.html().split(' ').join(' '));
|
||||
|
||||
// put the original content back to the textarea
|
||||
$element.html(_html);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
||||
function loadUser($obj, $string) {
|
||||
|
||||
// get userlist element
|
||||
var _obj = $obj.parent().find('.mention-userlist');
|
||||
|
||||
// show loader while loading
|
||||
//_obj.html('<li><div class="loader"></div></li>');
|
||||
|
||||
// show userlist
|
||||
_obj.show();
|
||||
|
||||
// start ajax request
|
||||
jQuery.getJSON(opts.searchUrl + '&keyword=' + $string + '&space_id=8', function (json) {
|
||||
|
||||
// remove existings entries
|
||||
_obj.find('li').remove();
|
||||
|
||||
if (json.length > 0) {
|
||||
|
||||
for (var i = 0; i < json.length; i++) {
|
||||
|
||||
// build <li> entry
|
||||
var str = '<li id="user_' + json[i].guid + '"><a tabindex="-1" href="javascript:$.fn.mention.addUser(\'' + $obj.attr('id') + '\',\'' + json[i].guid + '\', \'' + json[i].displayName + '\', ' + searchStart + ', ' + searchEnd + ');"><img class="img-rounded" src="' + json[i].image + '" height="20" width="20" alt=""/> ' + json[i].displayName + '</a></li>';
|
||||
|
||||
// append the entry to the <ul> list
|
||||
_obj.append(str);
|
||||
|
||||
}
|
||||
|
||||
// check if the list is empty
|
||||
if (_obj.children().length == 0) {
|
||||
// hide userpicker, if it is
|
||||
_obj.hide();
|
||||
}
|
||||
|
||||
// reset the variable for arrows keys
|
||||
chosen = "";
|
||||
|
||||
} else {
|
||||
|
||||
// hide userpicker, if no user was found
|
||||
_obj.hide();
|
||||
}
|
||||
|
||||
// remove hightlight
|
||||
_obj.find('li').removeHighlight();
|
||||
|
||||
// add new highlight matching strings
|
||||
_obj.find('li').highlight($string);
|
||||
|
||||
// add selection to the first space entry
|
||||
_obj.find('li:eq(0)').addClass('selected');
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Update the height
|
||||
//
|
||||
$.fn.mention.updateMentionContainerSize = function ($obj) {
|
||||
|
||||
// set mention overlay height to textarea height
|
||||
$obj.parent().css({
|
||||
height: $obj.outerHeight() + "px"
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// Update mention overlay with modified textarea content
|
||||
//
|
||||
$.fn.mention.updateMentionOverlay = function ($obj) {
|
||||
|
||||
// create a delay to get the newest content after the keydown event
|
||||
var _updateInterval = setInterval(function () {
|
||||
|
||||
// replace textfield spaces and line breaks with html codes
|
||||
var _content = $obj.val().split(' ').join(' ').replace(/\n/g, "<br>");
|
||||
|
||||
// update mention overlay with modified html content
|
||||
$obj.parent().find('.mention-overlay').html(_content);
|
||||
|
||||
// check if username is there
|
||||
for (var i = 0; i < $.fn.mention.defaults.arrUser.length; i++) {
|
||||
|
||||
|
||||
if ($obj.val().search($.fn.mention.defaults.arrUser[i]['name']) > -1) {
|
||||
|
||||
// save current textarea content
|
||||
var _value = $obj.parent().find('.mention-overlay').html();
|
||||
|
||||
// replace name through a <span> tag with user details
|
||||
_value = _value.replace($.fn.mention.defaults.arrUser[i]['name'], '<span data-guid="' + $.fn.mention.defaults.arrUser[i]['guid'] + '">' + $.fn.mention.defaults.arrUser[i]['name'] + '</span>');
|
||||
|
||||
// add modified content to mention overlay
|
||||
$obj.parent().find('.mention-overlay').html(_value);
|
||||
|
||||
} else {
|
||||
// remove user from array, if he didn't exists in the textarea anymore
|
||||
$.fn.mention.defaults.arrUser.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// set textarea height to mention container
|
||||
$.fn.mention.updateMentionContainerSize($obj);
|
||||
|
||||
// delete interval
|
||||
clearInterval(_updateInterval);
|
||||
|
||||
}, 1);
|
||||
|
||||
}
|
||||
|
||||
$.fn.mention.addUser = function ($element_id, $guid, $name, $start, $end) {
|
||||
|
||||
// replace current search input with username
|
||||
$('#' + $element_id).textrange('set', $start - 1, $end - ($start - 2));
|
||||
$('#' + $element_id).textrange('replace', $name + " ");
|
||||
|
||||
// get cursor position after the new inserted username
|
||||
var _newEnd = $('#' + $element_id).textrange('get').end;
|
||||
|
||||
// remove the username selection and set the cursor after the username
|
||||
$('#' + $element_id).textrange('set', _newEnd, 0);
|
||||
|
||||
// update the array with a new user
|
||||
$.fn.mention.updateArray($name, $guid);
|
||||
|
||||
// set textarea height to mention container
|
||||
$.fn.mention.updateMentionOverlay($('#' + $element_id));
|
||||
|
||||
// reset userlist state
|
||||
$.fn.mention.defaults.stateUserList = false;
|
||||
|
||||
// reset userlist elements
|
||||
$('#' + $element_id).parent().find('.mention-userlist').html('<li><div class="loader"></div></li>');
|
||||
$('#' + $element_id).parent().find('.mention-userlist').hide();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Update array with new users
|
||||
//
|
||||
$.fn.mention.updateArray = function (username, userguid) {
|
||||
|
||||
// create a new array element
|
||||
$.fn.mention.defaults.arrUser.push(new Array());
|
||||
|
||||
// get the count of the created array element
|
||||
var count = $.fn.mention.defaults.arrUser.length - 1;
|
||||
|
||||
// update properties
|
||||
$.fn.mention.defaults.arrUser[count]['name'] = username;
|
||||
$.fn.mention.defaults.arrUser[count]['guid'] = userguid;
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// empty the elements (for example after ajax submits)
|
||||
//
|
||||
$.fn.mention.reset = function ($element) {
|
||||
|
||||
// empty elements
|
||||
$($element).parent().find('.mention-html-content').val('');
|
||||
$($element).parent().find('.mention-overlay').empty();
|
||||
|
||||
// change container size to one line
|
||||
$($element).parent().parent().find('.mention-container').css({height: $($element).outerHeight()});
|
||||
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// set the position of the userlist under the current textfield
|
||||
//
|
||||
$.fn.mention.setPosition = function ($obj) {
|
||||
|
||||
// get the absolute position for the textarea inside the body
|
||||
var _top = $obj.offset().top - $(window).scrollTop();
|
||||
var _left = $obj.offset().left - $(window).scrollLeft();
|
||||
|
||||
// set mention userlist to the right position
|
||||
$obj.parent().find('.mention-userlist').css({
|
||||
position: "fixed",
|
||||
top: _top + $obj.outerHeight() - 4,
|
||||
left: _left,
|
||||
width: $obj.outerWidth()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
// plugin defaults
|
||||
$.fn.mention.defaults = {
|
||||
arrUser: new Array(),
|
||||
stateUserList: false,
|
||||
searchString: '',
|
||||
searchUrl: '',
|
||||
padding: '6px 12px',
|
||||
border: '2px solid transparent',
|
||||
color: '#ffffff',
|
||||
fontFamily: "'Open Sans', sans-serif",
|
||||
fontSize: '14px',
|
||||
fontWeight: '400',
|
||||
lineHeight: '20px',
|
||||
minHeight: '34px',
|
||||
borderRadius: '4px'
|
||||
};
|
210
js/jquery.textrange.js
Executable file
210
js/jquery.textrange.js
Executable file
@ -0,0 +1,210 @@
|
||||
/**
|
||||
* jquery-textrange
|
||||
* A jQuery plugin for getting, setting and replacing the selected text in input fields and textareas.
|
||||
* See the [wiki](https://github.com/dwieeb/jquery-textrange/wiki) for usage and examples.
|
||||
*
|
||||
* (c) 2013 Daniel Imhoff <dwieeb@gmail.com> - danielimhoff.com
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
var browserType,
|
||||
|
||||
textrange = {
|
||||
|
||||
/**
|
||||
* $().textrange() or $().textrange('get')
|
||||
*
|
||||
* Retrieves an object containing the start and end location of the text range, the length of the range and the
|
||||
* substring of the range.
|
||||
*
|
||||
* @param (optional) property
|
||||
* @return An object of properties including position, start, end, length, and text or a specific property.
|
||||
*/
|
||||
get: function(property) {
|
||||
return _textrange[browserType].get.apply(this, [property]);
|
||||
},
|
||||
|
||||
/**
|
||||
* $().textrange('set')
|
||||
*
|
||||
* Sets the selected text of an object by specifying the start and length of the selection.
|
||||
*
|
||||
* The start and length parameters are identical to PHP's substr() function with the following changes:
|
||||
* - excluding start will select all the text in the field.
|
||||
* - passing 0 for length will set the cursor at start. See $().textrange('setcursor')
|
||||
*
|
||||
* @param (optional) start
|
||||
* @param (optional) length
|
||||
*
|
||||
* @see http://php.net/manual/en/function.substr.php
|
||||
*/
|
||||
set: function(start, length) {
|
||||
var s = parseInt(start),
|
||||
l = parseInt(length),
|
||||
e;
|
||||
|
||||
if (typeof start === 'undefined') {
|
||||
s = 0;
|
||||
}
|
||||
else if (start < 0) {
|
||||
s = this.val().length + s;
|
||||
}
|
||||
|
||||
if (typeof length === 'undefined') {
|
||||
e = this.val().length;
|
||||
}
|
||||
else if (length >= 0) {
|
||||
e = s + l;
|
||||
}
|
||||
else {
|
||||
e = this.val().length + l;
|
||||
}
|
||||
|
||||
_textrange[browserType].set.apply(this, [s, e]);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* $().textrange('setcursor')
|
||||
*
|
||||
* Sets the cursor at a position of the text field.
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
setcursor: function(position) {
|
||||
return this.textrange('set', position, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* $().textrange('replace')
|
||||
* Replaces the selected text in the input field or textarea with text.
|
||||
*
|
||||
* @param text The text to replace the selection with.
|
||||
*/
|
||||
replace: function(text) {
|
||||
_textrange[browserType].replace.apply(this, [text]);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Alias for $().textrange('replace')
|
||||
*/
|
||||
insert: function(text) {
|
||||
return this.textrange('replace', text);
|
||||
}
|
||||
},
|
||||
|
||||
_textrange = {
|
||||
xul: {
|
||||
get: function(property) {
|
||||
var props = {
|
||||
position: this[0].selectionStart,
|
||||
start: this[0].selectionStart,
|
||||
end: this[0].selectionEnd,
|
||||
length: this[0].selectionEnd - this[0].selectionStart,
|
||||
text: this.val().substring(this[0].selectionStart, this[0].selectionEnd)
|
||||
};
|
||||
|
||||
return typeof property === 'undefined' ? props : props[property];
|
||||
},
|
||||
|
||||
set: function(start, end) {
|
||||
this[0].selectionStart = start;
|
||||
this[0].selectionEnd = end;
|
||||
},
|
||||
|
||||
replace: function(text) {
|
||||
var start = this[0].selectionStart;
|
||||
this.val(this.val().substring(0, this[0].selectionStart) + text + this.val().substring(this[0].selectionEnd, this.val().length));
|
||||
this[0].selectionStart = start;
|
||||
this[0].selectionEnd = start + text.length;
|
||||
}
|
||||
},
|
||||
|
||||
msie: {
|
||||
get: function(property) {
|
||||
var range = document.selection.createRange();
|
||||
|
||||
if (typeof range === 'undefined') {
|
||||
return {
|
||||
position: 0,
|
||||
start: 0,
|
||||
end: this[0].val().length,
|
||||
length: this[0].val().length,
|
||||
text: this.val()
|
||||
};
|
||||
}
|
||||
|
||||
var rangetext = this[0].createTextRange();
|
||||
var rangetextcopy = rangetext.duplicate();
|
||||
|
||||
rangetext.moveToBookmark(range.getBookmark());
|
||||
rangetextcopy.setEndPoint('EndToStart', rangetext);
|
||||
|
||||
return {
|
||||
position: rangetextcopy.text.length,
|
||||
start: rangetextcopy.text.length,
|
||||
end: rangetextcopy.text.length + range.text.length,
|
||||
length: range.text.length,
|
||||
text: range.text
|
||||
};
|
||||
},
|
||||
|
||||
set: function(start, end) {
|
||||
var range = this[0].createTextRange();
|
||||
|
||||
if (typeof range === 'undefined') {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (typeof start !== 'undefined') {
|
||||
range.moveStart('character', start);
|
||||
range.collapse();
|
||||
}
|
||||
|
||||
if (typeof end !== 'undefined') {
|
||||
range.moveEnd('character', end - start);
|
||||
}
|
||||
|
||||
range.select();
|
||||
},
|
||||
|
||||
replace: function(text) {
|
||||
document.selection.createRange().text = text;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.textrange = function(method) {
|
||||
if (typeof browserType === 'undefined') {
|
||||
browserType = 'selectionStart' in this[0] ? 'xul' : document.selection ? 'msie' : 'unknown';
|
||||
}
|
||||
|
||||
// I don't know how to support this browser. :c
|
||||
if (browserType === 'unknown') {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Prevents unpleasant behaviour for textareas in IE:
|
||||
// If you have a textarea which is too wide to be displayed entirely and therfore has to be scrolled horizontally,
|
||||
// then typing one character after another will scroll the page automatically to the right at the moment you reach
|
||||
// the right border of the visible part. But calling the focus function causes the page to be scrolled to the left
|
||||
// edge of the textarea. Immediately after that jump to the left side, the content is scrolled back to the cursor
|
||||
// position, which leads to a flicker page every time you type a character.
|
||||
if (document.activeElement !== this[0]) {
|
||||
this[0].focus();
|
||||
}
|
||||
|
||||
if (typeof method === 'undefined' || typeof method !== 'string') {
|
||||
return textrange.get.apply(this);
|
||||
}
|
||||
else if (typeof textrange[method] === 'function') {
|
||||
return textrange[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
}
|
||||
else {
|
||||
$.error("Method " + method + " does not exist in jQuery.textrange");
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
@ -25,7 +25,8 @@
|
||||
* @package humhub.libs
|
||||
* @since 0.5
|
||||
*/
|
||||
class HHtml extends CHtml {
|
||||
class HHtml extends CHtml
|
||||
{
|
||||
|
||||
/**
|
||||
* Fixes the default yii ajaxLink with unregistering onClick Handlers first, before set new one.
|
||||
@ -36,13 +37,14 @@ class HHtml extends CHtml {
|
||||
* @param type $htmlOptions
|
||||
* @return type
|
||||
*/
|
||||
public static function ajaxLink($text, $url, $ajaxOptions = array(), $htmlOptions = array()) {
|
||||
public static function ajaxLink($text, $url, $ajaxOptions = array(), $htmlOptions = array())
|
||||
{
|
||||
|
||||
// Auto set csrf token
|
||||
if (isset($ajaxOptions['data']) && is_array($ajaxOptions['data']) && !isset($ajaxOptions['data'][Yii::app()->request->csrfTokenName])) {
|
||||
$ajaxOptions['data'][Yii::app()->request->csrfTokenName] = Yii::app()->request->csrfToken;
|
||||
}
|
||||
|
||||
|
||||
if (isset($htmlOptions['id'])) {
|
||||
$id = $htmlOptions['id'];
|
||||
$cs = Yii::app()->getClientScript();
|
||||
@ -63,7 +65,8 @@ class HHtml extends CHtml {
|
||||
* attributes are also recognized (see {@link clientChange} and {@link tag} for more details.)
|
||||
* @return string the generated button
|
||||
*/
|
||||
public static function ajaxSubmitButton($label, $url, $ajaxOptions = array(), $htmlOptions = array()) {
|
||||
public static function ajaxSubmitButton($label, $url, $ajaxOptions = array(), $htmlOptions = array())
|
||||
{
|
||||
if (isset($htmlOptions['id'])) {
|
||||
$id = $htmlOptions['id'];
|
||||
$cs = Yii::app()->getClientScript();
|
||||
@ -88,7 +91,8 @@ class HHtml extends CHtml {
|
||||
* attributes are also recognized (see {@link clientChange} and {@link tag} for more details.)
|
||||
* @return string the generated button
|
||||
*/
|
||||
public static function ajaxButton($label, $url, $ajaxOptions = array(), $htmlOptions = array()) {
|
||||
public static function ajaxButton($label, $url, $ajaxOptions = array(), $htmlOptions = array())
|
||||
{
|
||||
if (isset($htmlOptions['id'])) {
|
||||
$id = $htmlOptions['id'];
|
||||
$cs = Yii::app()->getClientScript();
|
||||
@ -100,7 +104,8 @@ class HHtml extends CHtml {
|
||||
return parent::ajaxButton($label, $url, $ajaxOptions, $htmlOptions);
|
||||
}
|
||||
|
||||
public static function encodeJSParam($val) {
|
||||
public static function encodeJSParam($val)
|
||||
{
|
||||
|
||||
$val = str_replace("'", "\'", $val);
|
||||
$val = str_replace("'", '\"', $val);
|
||||
@ -114,7 +119,8 @@ class HHtml extends CHtml {
|
||||
* @param type $timestamp
|
||||
* @return type
|
||||
*/
|
||||
public static function timeago($timestamp) {
|
||||
public static function timeago($timestamp)
|
||||
{
|
||||
if (is_numeric($timestamp)) {
|
||||
$timestamp = date('Y-m-d H:i:s', $timestamp);
|
||||
}
|
||||
@ -131,7 +137,8 @@ class HHtml extends CHtml {
|
||||
* @param array $htmlOptions
|
||||
* @return string
|
||||
*/
|
||||
public static function postLink($text, $url = '#', $htmlOptions = array()) {
|
||||
public static function postLink($text, $url = '#', $htmlOptions = array())
|
||||
{
|
||||
|
||||
$id = "";
|
||||
if (!isset($htmlOptions['id'])) {
|
||||
@ -159,17 +166,21 @@ class HHtml extends CHtml {
|
||||
|
||||
/**
|
||||
* Converts an given Ascii Text into a HTML Block
|
||||
* @param boolean $allowHtml transform user names in links
|
||||
* @param boolean $allowEmbed Sets if comitted video links will embedded
|
||||
*
|
||||
* Tasks:
|
||||
* nl2br
|
||||
* oembed urls
|
||||
*/
|
||||
public static function enrichText($text) {
|
||||
public static function enrichText($text)
|
||||
{
|
||||
|
||||
$maxOembedCount = 3; // Maximum OEmbeds
|
||||
$oembedCount = 0; // OEmbeds used
|
||||
$maxOembedCount = 3; // Maximum OEmbeds
|
||||
$oembedCount = 0; // OEmbeds used
|
||||
|
||||
$text = preg_replace_callback('/http(.*?)(\s|$)/i', function($match) use (&$oembedCount, &$maxOembedCount) {
|
||||
|
||||
$text = preg_replace_callback('/http(.*?)(\s|$)/i', function ($match) use (&$oembedCount, &$maxOembedCount) {
|
||||
|
||||
// Try use oembed
|
||||
if ($maxOembedCount > $oembedCount) {
|
||||
@ -183,11 +194,51 @@ class HHtml extends CHtml {
|
||||
return HHtml::link($match[0], $match[0], array('target' => '_blank'));
|
||||
}, $text);
|
||||
|
||||
|
||||
# breaks links!?
|
||||
#$text = nl2br($text);
|
||||
|
||||
$text = str_replace("\n", "<br />\n", $text);
|
||||
|
||||
// get user details from guids
|
||||
$text = self::translateUserMentioning($text, true);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate guids from users to username
|
||||
* @param strint $text Contains the complete message
|
||||
* @param boolean $buildAnchors Wrap the username with a link to the profile, if it's true
|
||||
*
|
||||
*/
|
||||
public static function translateUserMentioning($text, $buildAnchors = true)
|
||||
{
|
||||
// save hits of @ char
|
||||
$hits = substr_count($text, ' @');
|
||||
|
||||
// loop for every founded @ char
|
||||
for ($i = 0; $i < $hits; $i++) {
|
||||
|
||||
// extract user guid
|
||||
$guid = substr($text, strpos($text, ' @'), 38);
|
||||
|
||||
// load user row from database
|
||||
$user = User::model()->findByAttributes(array('guid' => substr($guid, 2)));
|
||||
|
||||
// make user clickable if Html is allowed
|
||||
if ($buildAnchors == true) {
|
||||
$link = ' <a href="' . $user->getProfileUrl() . '" target="_self">' . $user->getDisplayName() . '</a>';
|
||||
} else {
|
||||
$link = " ". $user->getDisplayName();
|
||||
}
|
||||
|
||||
// replace guid with profile link and username
|
||||
$text = str_replace($guid, $link, $text);
|
||||
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -93,4 +93,14 @@ class ActivityModule extends CWebModule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted the activity content before delivery
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
public static function formatOutput($text) {
|
||||
$text = HHtml::translateUserMentioning($text, false);
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
<?php $this->beginContent('application.modules_core.activity.views.activityLayout', array('activity' => $activity)); ?>
|
||||
<?php $this->beginContent('application.modules_core.activity.views.activityLayout', array('activity' => $activity)); ?>
|
||||
|
||||
<strong><?php echo $user->displayName; ?></strong>
|
||||
wrote a new comment "<?php echo Helpers::trimText($target->message, 100); ?>".
|
||||
wrote a new comment "
|
||||
<?php
|
||||
$text = ActivityModule::formatOutput($target->message);
|
||||
echo Helpers::trimText($text, 100);
|
||||
?>
|
||||
".
|
||||
|
||||
<?php $this->endContent(); ?>
|
||||
|
@ -31,7 +31,7 @@
|
||||
<tbody><tr>
|
||||
<td valign="top" class="textContent">
|
||||
<strong><?php echo $user->displayName; ?></strong> <?php echo Yii::t('CommentModule.base', 'wrote a new comment'); ?><?php if ($workspace != null && Wall::$currentType != Wall::TYPE_SPACE): ?> in <strong><?php echo Helpers::truncateText($workspace->name, 25); ?></strong><?php endif; ?>:<br/>
|
||||
<?php echo $target->message; ?>
|
||||
<?php echo ActivityModule::formatOutput($target->message); ?>
|
||||
<br/>
|
||||
<a href="<?php echo Yii::app()->createUrl('wall/perma/content', array('model' => 'Comment', 'id' => $target->id)); ?>"><?php echo Yii::t('CommentModule.base', 'go to post'); ?></a>
|
||||
</td>
|
||||
|
@ -32,7 +32,7 @@
|
||||
<tbody><tr>
|
||||
<td valign="top" class="textContent">
|
||||
<strong><?php echo $creator->displayName; ?></strong> <?php echo Yii::t('CommentModule.base', 'also commented'); ?> <?php echo $targetObject->getContentTitle(); ?><?php if ($workspace != null && Wall::$currentType != Wall::TYPE_SPACE): ?> in <strong><?php echo Helpers::truncateText($workspace->name, 25); ?></strong><?php endif; ?>:<br/>
|
||||
<?php echo $sourceObject->message; ?>
|
||||
<?php echo NotificationModule::formatOutput($sourceObject->message); ?>
|
||||
<br/>
|
||||
<a href="<?php echo $notification->getUrl(); ?>"><?php echo Yii::t('CommentModule.base', 'go to post'); ?></a>
|
||||
</td>
|
||||
|
@ -31,7 +31,7 @@
|
||||
<tbody><tr>
|
||||
<td valign="top" class="textContent">
|
||||
<strong><?php echo $creator->displayName; ?></strong> <?php echo Yii::t('CommentModule.base', 'commented your'); ?> <?php echo $targetObject->getContentTitle(); ?><?php if ($workspace != null && Wall::$currentType != Wall::TYPE_SPACE): ?> in <strong><?php echo Helpers::truncateText($workspace->name, 25); ?></strong><?php endif; ?>:<br/>
|
||||
<?php echo $sourceObject->message; ?>
|
||||
<?php echo NotificationModule::formatOutput($sourceObject->message); ?>
|
||||
<br/>
|
||||
<a href="<?php echo $notification->getUrl(); ?>"><?php echo Yii::t('CommentModule.base', 'go to post'); ?></a>
|
||||
</td>
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
|
||||
<?php echo CHtml::textArea("message", Yii::t('CommentModule.base', ""), array('id' => 'newCommentForm_' . $id, 'rows' => '1', 'class' => 'form-control autosize', 'placeholder' => 'Write a new comment...')); ?>
|
||||
<?php echo CHtml::textArea("message", Yii::t('CommentModule.base', ""), array('id' => 'newCommentForm_' . $id, 'rows' => '1', 'class' => 'form-control autosize commentForm', 'placeholder' => 'Write a new comment...')); ?>
|
||||
<?php
|
||||
echo HHtml::ajaxSubmitButton(Yii::t('base', 'Post'), CHtml::normalizeUrl(array('/comment/comment/post')), array(
|
||||
'beforeSend' => "function() {
|
||||
@ -55,12 +55,12 @@
|
||||
}",
|
||||
), array(
|
||||
'id' => "comment_create_post_" . $id,
|
||||
'class' => 'btn btn-small btn-primary hide'
|
||||
'class' => 'btn btn-small btn-primary',
|
||||
'style' => 'position: absolute; top: -3000px; left: -3000px;',
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo Chtml::endForm(); ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -68,26 +68,37 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$('#newCommentForm_<?php echo $id; ?>').mention({
|
||||
searchUrl: '<?php echo Yii::app()->createAbsoluteUrl('user/search/json') ?>'
|
||||
});
|
||||
|
||||
// Fire click event for comment button by typing enter
|
||||
$('#newCommentForm_<?php echo $id; ?>').keydown(function (event) {
|
||||
|
||||
if (event.keyCode == 13) {
|
||||
|
||||
event.cancelBubble = true;
|
||||
event.returnValue = false;
|
||||
jQuery('#comment_create_post_<?php echo $id; ?>').click();
|
||||
|
||||
// empty input
|
||||
$(this).val('');
|
||||
if ($.fn.mention.defaults.stateUserList == false) {
|
||||
|
||||
event.cancelBubble = true;
|
||||
event.returnValue = false;
|
||||
|
||||
$('#comment_create_post_<?php echo $id; ?>').focus();
|
||||
$('#comment_create_post_<?php echo $id; ?>').click();
|
||||
|
||||
// empty input
|
||||
$(this).val('');
|
||||
}
|
||||
|
||||
|
||||
// correct the textfield height
|
||||
//jQuery('#newCommentForm_<?php echo $id; ?>').css({'height': '13px'});
|
||||
}
|
||||
|
||||
return event.returnValue;
|
||||
|
||||
});
|
||||
|
||||
// set the size for one row (Firefox)
|
||||
$('#newCommentForm_<?php echo $id; ?>').css({height: '36px'});
|
||||
|
||||
// add autosize function to input
|
||||
$('.autosize').autosize();
|
||||
|
@ -17,7 +17,12 @@
|
||||
|
||||
<div class="media-body">
|
||||
<h4 class="media-heading"><a href="<?php echo $user->getProfileUrl(); ?>"><?php echo $user->displayName; ?></a> <small><?php echo HHtml::timeago($comment->created_at); ?></small></h4>
|
||||
<span class="content"><?php print nl2br($comment->message); ?></span>
|
||||
<span class="content">
|
||||
<?php
|
||||
print HHtml::enrichText($comment->message);
|
||||
//print nl2br($comment->message);
|
||||
?>
|
||||
</span>
|
||||
|
||||
<?php //echo CHtml::link(Yii::t('base', "Delete"), '#'); ?>
|
||||
|
||||
|
@ -99,4 +99,14 @@ class NotificationModule extends CWebModule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted the notification content before delivery
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
public static function formatOutput($text) {
|
||||
$text = HHtml::translateUserMentioning($text, false);
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
@ -31,7 +31,7 @@
|
||||
<td valign="top" class="textContent">
|
||||
<strong><?php echo $user->displayName; ?></strong> <?php echo Yii::t('PostModule.base', 'wrote a new post'); ?><?php if ($workspace != null && Wall::$currentType != Wall::TYPE_SPACE): ?> in <strong><?php echo Helpers::truncateText($workspace->name, 25); ?></strong><?php endif; ?><br/>
|
||||
<br/>
|
||||
<?php echo $target->message; ?><br>
|
||||
<?php echo ActivityModule::formatOutput($target->message); ?><br>
|
||||
<a href="<?php echo Yii::app()->createUrl('wall/perma/content', array('model' => get_class($target), 'id' => $target->id)); ?>"><?php echo Yii::t('PostModule.base', 'Read online...'); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -15,6 +15,7 @@
|
||||
<?php $this->beginContent('application.modules_core.wall.views.wallLayout', array('object' => $post)); ?>
|
||||
<div id="post-content-<?php echo $post->id; ?>" style="overflow: hidden; margin-bottom: 5px;">
|
||||
<?php print HHtml::enrichText($post->message); ?>
|
||||
|
||||
</div>
|
||||
<a class="more-link-post hidden" id="more-link-post-<?php echo $post->id; ?>" data-state="down"
|
||||
style="margin: 20px 0 20px 0;" href="javascript:showMore(<?php echo $post->id; ?>);"><i
|
||||
|
@ -7,7 +7,8 @@
|
||||
* @package humhub.modules_core.user.controllers
|
||||
* @since 0.5
|
||||
*/
|
||||
class SearchController extends Controller {
|
||||
class SearchController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* JSON Search for Users
|
||||
@ -21,88 +22,101 @@ class SearchController extends Controller {
|
||||
* - city
|
||||
* - image
|
||||
* - profile link
|
||||
* - isMember
|
||||
*
|
||||
* @todo Add limit for workspaces
|
||||
*/
|
||||
public function actionJson() {
|
||||
public function actionJson()
|
||||
{
|
||||
|
||||
$results = array();
|
||||
$keyword = Yii::app()->request->getParam('keyword', ""); // guid of user/workspace
|
||||
$page = (int) Yii::app()->request->getParam('page', 1); // current page (pagination)
|
||||
$limit = (int) Yii::app()->request->getParam('limit', HSetting::Get('paginationSize')); // current page (pagination)
|
||||
$spaceId = (int) Yii::app()->request->getParam('space_id', 0);
|
||||
$hitCount = 0;
|
||||
$spaceId = (int)Yii::app()->request->getParam('space_id', 0);
|
||||
|
||||
$keyword = Yii::app()->input->stripClean($keyword);
|
||||
// save current displayNameFormat for users
|
||||
$displayFormat = HSetting::Get('displayNameFormat');
|
||||
|
||||
// We need a least 3 characters
|
||||
if (strlen($keyword) < 3) {
|
||||
print CJSON::encode($results);
|
||||
Yii::app()->end();
|
||||
}
|
||||
// get members of the current space
|
||||
$spaceMembers = SpaceMembership::model()->findAll('space_id=:space_id', array(':space_id' => $spaceId));
|
||||
|
||||
if (strlen($keyword) > 2) {
|
||||
|
||||
if (strpos($keyword, "@") === false) {
|
||||
$keyword = str_replace(".", "", $keyword);
|
||||
$query = "(title:" . $keyword . "* OR email:" . $keyword . "*) AND (model:User)";
|
||||
} else {
|
||||
$query = "email:" . $keyword . " AND (model:User)";
|
||||
if ($displayFormat == "{username}") {
|
||||
|
||||
// build like search string
|
||||
$match = addcslashes($keyword, '%_');
|
||||
|
||||
// build sql string
|
||||
$q = new CDbCriteria();
|
||||
$q->addSearchCondition('username', $match);
|
||||
|
||||
// find users by committed keyword
|
||||
$users = User::model()->findAll( $q );
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
||||
if ($user != null) {
|
||||
|
||||
// push array with new user entry
|
||||
$userInfo = array();
|
||||
$userInfo['guid'] = $user->guid;
|
||||
$userInfo['displayName'] = $user->displayName;
|
||||
$userInfo['image'] = $user->getProfileImage()->getUrl();
|
||||
$userInfo['link'] = $user->getUrl();
|
||||
$userInfo['isMember'] = $this->checkMembership($spaceMembers, $user->id);
|
||||
$results[] = $userInfo;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// get members of the current space
|
||||
$spaceMembers = SpaceMembership::model()->findAll('space_id=:space_id', array(':space_id'=>$spaceId));
|
||||
} else {
|
||||
|
||||
//$hits = HSearch::getInstance()->Find($query);
|
||||
//, $limit, $page
|
||||
$hits = new ArrayObject(
|
||||
HSearch::getInstance()->Find($query
|
||||
));
|
||||
// get matching database rows
|
||||
$profiles = Yii::app()->db->createCommand("SELECT user_id FROM profile WHERE firstname like '%" . $keyword . "%' OR lastname like '%" . $keyword . "%'")->queryAll();
|
||||
|
||||
$hitCount = count($hits);
|
||||
|
||||
// Limit Hits
|
||||
$hits = new LimitIterator($hits->getIterator(), ($page - 1) * $limit, $limit);
|
||||
// save rows count
|
||||
$hitCount = count($profiles);
|
||||
|
||||
// close function, if there are no results
|
||||
if ($hitCount == 0) {
|
||||
print CJSON::encode($results);
|
||||
Yii::app()->end();
|
||||
}
|
||||
|
||||
foreach ($profiles as $profile) {
|
||||
|
||||
foreach ($hits as $hit) {
|
||||
$doc = $hit->getDocument();
|
||||
$model = $doc->getField("model")->value;
|
||||
// get user id
|
||||
$userId = $profile['user_id'];
|
||||
|
||||
if ($model == "User") {
|
||||
$userId = $doc->getField('pk')->value;
|
||||
$user = User::model()->findByPk($userId);
|
||||
// find user in database
|
||||
$user = User::model()->findByPk($userId);
|
||||
|
||||
if ($user != null) {
|
||||
|
||||
// push array with new user entry
|
||||
$userInfo = array();
|
||||
$userInfo['guid'] = $user->guid;
|
||||
$userInfo['displayName'] = $user->displayName;
|
||||
$userInfo['image'] = $user->getProfileImage()->getUrl();
|
||||
$userInfo['link'] = $user->getUrl();
|
||||
$userInfo['isMember'] = $this->checkMembership($spaceMembers, $userId);
|
||||
$results[] = $userInfo;
|
||||
|
||||
if ($user != null) {
|
||||
$userInfo = array();
|
||||
$userInfo['guid'] = $user->guid;
|
||||
$userInfo['displayName'] = $user->displayName;
|
||||
$userInfo['image'] = $user->getProfileImage()->getUrl();
|
||||
$userInfo['link'] = $user->getUrl();
|
||||
$userInfo['isMember'] = $this->checkMembership($spaceMembers, $userId);
|
||||
$results[] = $userInfo;
|
||||
} else {
|
||||
Yii::log("Could not load use with id " . $userId . " from search index!", CLogger::LEVEL_ERROR);
|
||||
}
|
||||
} else {
|
||||
Yii::log("Got no user hit from search index!", CLogger::LEVEL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print CJSON::encode($results);
|
||||
Yii::app()->end();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check Membership of users
|
||||
*
|
||||
*/
|
||||
private function checkMembership($members, $userId) {
|
||||
private function checkMembership($members, $userId)
|
||||
{
|
||||
|
||||
// check if current user is member of this space
|
||||
foreach ($members as $member) {
|
||||
|
@ -64,10 +64,12 @@
|
||||
$('#notifyUserContainer').addClass('hidden');
|
||||
$('#notifiyUserInput').val('');
|
||||
$('.label-public').addClass('hidden');
|
||||
|
||||
$('#contentFrom_files').val('');
|
||||
$('#public').attr('checked', false);
|
||||
|
||||
//$('.contentForm').
|
||||
$.fn.mention.reset('.contentForm');
|
||||
|
||||
// Notify FileUploadButtonWidget to clear (by providing uploaderId)
|
||||
clearFileUpload('contentFormFiles');
|
||||
|
||||
@ -103,15 +105,6 @@
|
||||
<!-- content sharing -->
|
||||
<div class="pull-right">
|
||||
|
||||
<div class="checkbox hidden">
|
||||
<label>
|
||||
<?php echo CHtml::checkbox("visibility", "", array('id' => 'contentForm_visibility', 'class' => 'contentForm')); ?> <?php echo Yii::t('WallModule.base', 'Is public'); ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- <a class="tt btn btn-icon" href="" data-toggle="tooltip" data-placement="top" data-original-title="<?php /*echo Yii::t('WallModule.base', 'Notify related members about this post'); */ ?>"><i class="icon-bell-alt"></i></a>
|
||||
<a class="tt btn btn-icon" href="" data-toggle="tooltip" data-placement="top" data-original-title="<?php /*echo Yii::t('WallModule.base', 'Make public for nonmembers<br>and followers of this space'); */ ?>"><i class="icon-lock"></i></a>
|
||||
-->
|
||||
<span class="label label-success label-public hidden">Public</span>
|
||||
|
||||
<ul class="nav nav-pills preferences">
|
||||
@ -159,6 +152,10 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$('#contentForm_message').mention({
|
||||
searchUrl: '<?php echo Yii::app()->createAbsoluteUrl('user/search/json') ?>'
|
||||
});
|
||||
|
||||
// Hide options by default
|
||||
jQuery('.contentForm_options').hide();
|
||||
$('#contentFormError').hide();
|
||||
@ -189,6 +186,9 @@
|
||||
$('#notifiyUserInput_tag_input_field').focus();
|
||||
}
|
||||
|
||||
// set the size for one row (Firefox)
|
||||
$('textarea').css({height: '36px'});
|
||||
|
||||
// add autosize function to input
|
||||
$('.autosize').autosize();
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
<link href="<?php echo Yii::app()->baseUrl; ?>/resources/font-awesome/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="<?php echo Yii::app()->baseUrl; ?>/css/bootstrap-wysihtml5.css" rel="stylesheet">
|
||||
<link href="<?php echo Yii::app()->baseUrl; ?>/css/flatelements.css" rel="stylesheet">
|
||||
<link href="<?php echo Yii::app()->baseUrl; ?>/css/mention.css" rel="stylesheet">
|
||||
<!-- end: CSS -->
|
||||
|
||||
|
||||
@ -34,6 +35,8 @@
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/bootstrap3-wysihtml5.js"></script>
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/jquery.nicescroll.min.js"></script>
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/jquery.flatelements.js"></script>
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/jquery.textrange.js"></script>
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/jquery.mention.js"></script>
|
||||
|
||||
<!-- Global app functions -->
|
||||
<script type="text/javascript" src="<?php echo Yii::app()->baseUrl; ?>/js/app.js"></script>
|
||||
|
@ -204,7 +204,6 @@
|
||||
|
||||
})
|
||||
|
||||
|
||||
// load number of new notifications at page loading
|
||||
getNotifications();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user