2019-04-13 12:53:15 +00:00
// $('#contentField').on('keypress', function (e) {
// console.log(e, $(this).html());
//
// if (e.ctrlKey)
// return;
//
// setTimeout(() => {
// // console.log($(this).html());
// //
// const range = window.getSelection().getRangeAt(0);
// const endNode = range.endContainer;
// let end = range.endOffset;
//
// // console.log(range.startOffset, end);
//
// if (endNode !== this) {
// console.log('test');
// const textNodes = get_text_nodes_in(this);
// console.log(textNodes);
// for (let i = 0; i < textNodes.length; ++i) {
// if (textNodes[i] === endNode)
// break;
// end += textNodes[i].length;
// }
// }
//
// let html = $(this).html();
//
// if (/\ $/.test(html) && $(this).text().length === end) {
// end--;
// set_range(end, end, this);
// return;
// }
//
// let filter = html.replace(/<span class="mention">/g, "")
// .replace(/<span class="hashtag">/g, "")
// .replace(/<\/span>/g, "")
// .replace(/@[A-Za-z0-9._]+/g, (match) => `<span class="mention">${match}</span>`)
// .replace(/#[A-Za-z0-9._]+/g, (match) => `<span class="hashtag">${match}</span>`);
//
// console.log(range.startOffset, end);
// $(this).html(filter);
// set_range(end, end, this);
// }, 1);
const keys = [ 'Home' , 'End' , 'Insert' , 'Delete' , 'Enter' ] ;
$ ( '#contentField' ) . on ( 'keypress' , function ( e ) {
console . log ( e . key , e . code ) ;
if ( e . ctrlKey || e . key . indexOf ( 'Arrow' ) === 0 || keys . includes ( e . key ) )
return ;
2018-10-16 16:28:42 +00:00
2019-04-13 12:53:15 +00:00
console . log ( e . which ) ;
setTimeout ( ( ) => {
var range = window . getSelection ( ) . getRangeAt ( 0 ) ;
var end _node = range . endContainer ;
var end = range . endOffset ;
if ( end _node != this ) {
var text _nodes = get _text _nodes _in ( this ) ;
for ( var i = 0 ; i < text _nodes . length ; ++ i ) {
if ( text _nodes [ i ] == end _node ) {
break ;
}
end += text _nodes [ i ] . length ;
2018-10-16 16:28:42 +00:00
}
}
2019-04-13 12:53:15 +00:00
var html = $ ( this ) . html ( ) ;
if ( /\ $/ . test ( html ) && $ ( this ) . text ( ) . length == end ) {
end = end - 1 ;
set _range ( end , end , this ) ;
return ;
}
2018-10-16 16:28:42 +00:00
2019-04-13 12:53:15 +00:00
let filter = html . replace ( /<span class="[^"]*">([^<\/]*)<\/span>/g , '$1' )
. replace ( /@[A-Za-z0-9._]+/g , ( match ) => ` <span class="mention"> ${ match } </span> ` )
. replace ( /#[A-Za-z0-9_]+/g , ( match ) => ` <span class="hashtag"> ${ match } </span> ` ) ;
2018-10-16 16:28:42 +00:00
2019-04-13 12:53:15 +00:00
// var filter = html.replace(/(<b>)?\/([^<\/]*)(<\/b>)?/g, '\/$2');
// console.log(filter);
// filter = filter.replace(/(<b>)?([^<\/]*)\/(<\/b>)?/g, '$2\/');
// console.log(filter);
// filter = filter.replace(/(<b>)?\/([^<\/]*)\/(<\/b>)?/g, '<b>\/$2\/<\/b>');
// console.log(filter);
if ( ! /\ $/ . test ( $ ( this ) . html ( ) ) ) {
filter += ' ' ;
}
$ ( this ) . html ( filter ) ;
set _range ( end , end , this ) ;
} , 1 ) ;
2018-10-16 16:28:42 +00:00
} ) ;
2019-04-13 12:53:15 +00:00
// var range = window.getSelection().getRangeAt(0);
// var end_node = range.endContainer;
// var end = range.endOffset;
//
// if (end_node !== this) {
// const text_nodes = get_text_nodes_in(this);
// for (let i = 0; i < text_nodes.length; ++i) {
// if (text_nodes[i] === end_node) {
// break;
// }
// end += text_nodes[i].length;
// }
// }
//
// let html = $(this).html();
// if (/\ $/.test(html) && $(this).text().length === end) {
// end--;
// set_range(end, end, this);
// return;
// }
//
// let filter = html.replace(/<span class="mention">/g, "")
// .replace(/<span class="hashtag">/g, "")
// .replace(/<\/span>/g, "")
// .replace(/@[A-Za-z0-9._]+/g, function (match) {
// return `<span class="mention">${match}</span>`;
// })
// .replace(/#[A-Za-z0-9._]+/g, function (match) {
// return `<span class="hashtag">${match}</span>`;
// });
//
// if (!/ $/.test($(this).html())) {
// filter += ' ';
// }
// $(this).html(filter);
// set_range(end, end, this);
// })
// ;
2018-10-16 16:28:42 +00:00
$ ( '#contentField' ) . on ( 'mouseup' , function ( e ) {
if ( ! /\ $/ . test ( $ ( this ) . html ( ) ) ) {
return ;
}
var range = window . getSelection ( ) . getRangeAt ( 0 ) ;
var end = range . endOffset ;
var end _node = range . endContainer ;
if ( end _node != this ) {
var text _nodes = get _text _nodes _in ( this ) ;
for ( var i = 0 ; i < text _nodes . length ; ++ i ) {
if ( text _nodes [ i ] == end _node ) {
break ;
}
end += text _nodes [ i ] . length ;
}
}
if ( $ ( this ) . text ( ) . length == end ) {
end = end - 1 ;
set _range ( end , end , this ) ;
}
} ) ;
function get _text _nodes _in ( node ) {
var text _nodes = [ ] ;
if ( node . nodeType === 3 ) {
text _nodes . push ( node ) ;
} else {
var children = node . childNodes ;
for ( var i = 0 , len = children . length ; i < len ; ++ i ) {
var text _node ;
text _nodes . push . apply ( text _nodes , get _text _nodes _in ( children [ i ] ) ) ;
}
}
return text _nodes ;
}
function set _range ( start , end , element ) {
var range = document . createRange ( ) ;
range . selectNodeContents ( element ) ;
var text _nodes = get _text _nodes _in ( element ) ;
var foundStart = false ;
var char _count = 0 , end _char _count ;
for ( var i = 0 , text _node ; text _node = text _nodes [ i ++ ] ; ) {
end _char _count = char _count + text _node . length ;
if ( ! foundStart && start >= char _count && ( start < end _char _count || ( start === end _char _count && i < text _nodes . length ) ) ) {
range . setStart ( text _node , start - char _count ) ;
foundStart = true ;
}
if ( foundStart && end <= end _char _count ) {
range . setEnd ( text _node , end - char _count ) ;
break ;
}
char _count = end _char _count ;
}
var selection = window . getSelection ( ) ;
selection . removeAllRanges ( ) ;
selection . addRange ( range ) ;
}
$ . fn . selectRange = function ( start , end ) {
var e = document . getElementById ( $ ( this ) . attr ( 'id' ) ) ;
2018-12-30 17:56:34 +00:00
if ( ! e ) {
} else if ( e . setSelectionRange ) {
2018-10-16 16:28:42 +00:00
e . focus ( ) ;
e . setSelectionRange ( start , end ) ;
} /* WebKit */
else if ( e . createTextRange ) {
var range = e . createTextRange ( ) ;
range . collapse ( true ) ;
range . moveEnd ( 'character' , end ) ;
range . moveStart ( 'character' , start ) ;
range . select ( ) ;
} /* IE */
else if ( e . selectionStart ) {
e . selectionStart = start ;
e . selectionEnd = end ;
}
} ;
2018-12-30 17:52:30 +00:00
let postMedia = [ ] ;
2018-10-16 16:28:42 +00:00
function publishPost ( ) {
let isFilled = true ;
let content = $ ( '#contentField' ) . text ( ) ;
2018-12-30 17:52:30 +00:00
if ( postMedia . length === 0 && content === "" ) {
2018-10-16 16:28:42 +00:00
$ ( '#postModal #content' ) . addClass ( 'has-error' ) ;
isFilled = false ;
} else {
$ ( '#postModal #content' ) . addClass ( 'has-success' ) ;
}
if ( isFilled ) {
const replyTo = $ ( '#postModal #replyTo' ) . val ( ) ;
submitPost ( content , replyTo ) ;
2018-12-30 17:52:30 +00:00
} else {
addSnackbar ( 'primary' , 'Wir haben leider noch nicht erlernt, wie man leere Posts veröffentlicht.' ) ;
2018-10-16 16:28:42 +00:00
}
}
2018-12-30 17:52:30 +00:00
let uploadingFiles = [ ] ;
( function ( ) {
// file drag hover
function fileDragHover ( e ) {
e . stopPropagation ( ) ;
e . preventDefault ( ) ;
e . target . className = ( e . type == "dragover" ? "hover" : "" ) ;
}
// file selection
function fileSelectHandler ( e ) {
// cancel event and hover styling
fileDragHover ( e ) ;
// fetch FileList object
const files = e . target . files || e . dataTransfer . files ;
// process all File objects
let i = 0 ;
for ( let f of files ) {
const generalType = f . type . split ( '/' ) [ 0 ] ;
if ( postMedia . length + i > 4 || postMedia . find ( media => media . type !== 'image' || media . type !== generalType ) ) {
addSnackbar ( 'warning' , 'Du kannst maximal vier Bilder zu einem Post hinzufügen.' ) ;
2018-10-16 16:28:42 +00:00
continue ;
2018-12-30 17:52:30 +00:00
}
parseFile ( f ) ;
uploadFile ( f ) ;
i ++ ;
}
}
// output file information
function parseFile ( file ) {
$ ( '#postModalPublish' ) . addClass ( 'disabled' ) . attr ( 'disabled' , true ) ;
uploadingFiles . push ( file ) ;
2018-10-16 16:28:42 +00:00
2018-12-30 17:52:30 +00:00
const thumbnailEl = $ ( '<div class="post-image"></div>' ) ;
$ ( '.post-images' ) . append ( thumbnailEl ) ;
switch ( file . type . split ( '/' ) [ 0 ] ) {
case 'image' :
const reader = new FileReader ( ) ;
reader . addEventListener ( 'load' , ( ) => {
thumbnailEl . css ( 'background-image' , ` url( ${ reader . result } ) ` ) ;
} ) ;
2019-04-13 12:53:15 +00:00
reader . readAsDataURL ( file ) ;
2018-12-30 17:52:30 +00:00
if ( postMedia . length >= 4 )
$ ( '.postImageUpload' ) . hide ( ) ;
2019-04-13 12:53:15 +00:00
break ;
2018-12-30 17:52:30 +00:00
case 'video' :
const video = document . createElement ( 'video' ) ;
video . src = URL . createObjectURL ( file ) ;
video . addEventListener ( 'loadeddata' , ( ) => {
const width = video . videoWidth ;
const height = video . videoHeight ;
const canvas = document . createElement ( 'canvas' ) ;
canvas . width = width ;
canvas . height = height ;
canvas . getContext ( '2d' ) . drawImage ( video , 0 , 0 , width , height ) ;
thumbnailEl . css ( 'background-image' , ` url( ${ canvas . toDataURL ( ) } ) ` ) ;
} ) ;
$ ( '.postImageUpload' ) . hide ( ) ;
break ;
case 'audio' :
break ;
}
}
// upload JPEG files
function uploadFile ( file ) {
var xhr = new XMLHttpRequest ( ) ;
const allowedTypes = [ 'image/jpg' , 'image/jpeg' , 'image/gif' , 'image/png' , 'video/mp4' ] ;
if ( xhr . upload && allowedTypes . includes ( file . type ) && file . size <= 100000000 ) {
const formData = new FormData ( ) ;
formData . append ( 'postMedia' , file ) ;
$ . ajax ( {
url : '/user/uploadPostMedia' ,
method : 'POST' ,
data : formData ,
processData : false ,
contentType : false ,
success : ( data ) => {
postMedia . push ( {
type : data . type ,
path : data . path ,
} ) ;
uploadingFiles . splice ( uploadingFiles . indexOf ( file ) , 1 ) ;
2019-04-13 12:53:15 +00:00
if ( uploadingFiles . length === 0 ) {
2018-12-30 17:52:30 +00:00
$ ( '#postModalPublish' ) . removeClass ( 'disabled' ) . attr ( 'disabled' , false ) ;
}
} ,
2019-04-13 12:53:15 +00:00
error : ( ) => {
addSnackbar ( 'danger' , 'Es ist ein Fehler beim Hochladen aufgetreten' )
}
2018-10-16 16:28:42 +00:00
} ) ;
2018-12-30 17:52:30 +00:00
2018-10-16 16:28:42 +00:00
}
2018-12-30 17:52:30 +00:00
2018-10-16 16:28:42 +00:00
}
2018-12-30 17:52:30 +00:00
// initialize
function init ( ) {
var fileselect = $ ( '#postFiles' ) [ 0 ] ,
filedrag = $ ( '#postFiles' ) [ 0 ] ;
// submitbutton = $id("submitbutton");
if ( ! fileselect )
return ;
// file select
fileselect . addEventListener ( "change" , fileSelectHandler , false ) ;
// is XHR2 available?
var xhr = new XMLHttpRequest ( ) ;
if ( xhr . upload ) {
// file drop
filedrag . addEventListener ( "dragover" , fileDragHover , false ) ;
filedrag . addEventListener ( "dragleave" , fileDragHover , false ) ;
filedrag . addEventListener ( "drop" , fileSelectHandler , false ) ;
filedrag . style . display = "block" ;
}
2018-10-16 16:28:42 +00:00
}
2018-12-30 17:52:30 +00:00
// call initialization file
if ( window . File && window . FileList && window . FileReader ) {
init ( ) ;
}
} ) ( ) ;
$ ( '#postModal' )
. on ( 'hide.bs.modal' , function ( e ) {
if ( ! this . forceQuit && ( postMedia . length > 0 || $ ( '#contentField' ) . text ( ) . trim ( ) . length > 0 ) ) {
e . preventDefault ( ) ;
let allowClosing = false ;
const confirmModal = $ ( `
< div class = "modal fade" role = "dialog" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Post verwerfen ? < / h 4 >
< / d i v >
< div class = "modal-footer" >
< button class = "btn btn-sm btn-outline btn-red dismiss" type = "button" data - dismiss = "modal" > Ja , Post verwerfen < / b u t t o n >
< button class = "btn btn-sm btn-primary continue" type = "submit" data - dismiss = "modal" > Nein , Post behalten < / b u t t o n >
< / d i v >
< / d i v >
< / d i v >
< / d i v >
` );
confirmModal . modal ( 'show' ) ;
$ ( '.dismiss' , confirmModal ) . click ( ( ) => {
allowClosing = true ;
this . forceQuit = true ;
$ ( this ) . modal ( 'hide' ) ;
} ) ;
$ ( '.continue' , confirmModal ) . click ( ( ) => {
allowClosing = true ;
} ) ;
confirmModal
. on ( 'hide.bs.modal' , function ( e ) {
if ( ! allowClosing )
e . preventDefault ( ) ;
} )
. on ( 'hidden.bs.modal' , function ( ) {
$ ( this ) . remove ( ) ;
} ) ;
} else {
this . forceQuit = false ;
}
} )
. on ( 'hidden.bs.modal' , ( ) => {
$ ( '#postModal #replyTo' ) . val ( - 1 ) ;
2019-04-13 12:53:15 +00:00
if ( postMedia . length > 0 ) {
2018-12-30 17:52:30 +00:00
postMedia . forEach ( media => {
$ . ajax ( {
url : '/user/deletePostMedia' ,
method : 'POST' ,
data : {
path : media . path
}
} ) ;
} ) ;
}
resetPostForm ( ) ;
$ ( '#postModalBody > *:not(#postForm)' ) . remove ( ) ;
$ ( '#postForm' ) . show ( ) ;
$ ( '#postModal .modal-footer' ) . show ( ) ;
} ) ;
function resetPostForm ( ) {
uploadingFiles = [ ] ;
postMedia = [ ] ;
$ ( '.post-images' ) . empty ( ) ;
$ ( '.postImageUpload' ) . show ( ) ;
$ ( '#contentField' ) . text ( '' ) ;
}
2018-10-16 16:28:42 +00:00
function submitPost ( content , replyTo ) {
2018-12-30 17:52:30 +00:00
if ( postMedia . length > 4 ) {
2018-10-16 16:28:42 +00:00
return ;
}
2018-12-30 17:52:30 +00:00
const body = $ ( '#postModalBody' ) ;
2018-10-16 16:28:42 +00:00
$ . ajax ( {
2018-10-17 11:56:22 +00:00
url : "/user/publishPost" ,
2018-10-16 16:28:42 +00:00
method : 'POST' ,
data : {
content ,
replyTo ,
postMedia
} ,
beforeSend : function ( ) {
2018-12-30 17:52:30 +00:00
body . children ( ) . hide ( ) . parent ( ) . append ( '<div class="loadingSpinner"></div>' ) ;
$ ( '#postModal .modal-footer' ) . hide ( ) ;
resetPostForm ( ) ;
2018-10-16 16:28:42 +00:00
} ,
success : function ( data ) {
2019-01-08 21:42:54 +00:00
console . log ( data ) ;
2018-12-30 17:52:30 +00:00
$ ( '.loadingSpinner' , body ) . remove ( ) ;
2019-01-08 21:42:54 +00:00
body . append ( `
< div class = "alert alert-${data.success ? 'success' : 'danger'}" role = "alert" >
< b > $ { data . title } < / b >
$ { data . message . join ( '<br>' ) }
< / d i v >
` );
2019-04-13 12:53:15 +00:00
if ( data . buttons ) {
2019-01-08 21:42:54 +00:00
const footer = $ ( '<div class="modal-footer"></div>' ) ;
body . parent ( ) . append ( footer ) ;
data . buttons . forEach ( button => {
let btn ;
2019-04-13 12:53:15 +00:00
if ( button . action ) {
2019-01-08 21:42:54 +00:00
btn = ` <a href=" ${ button . action } " class="btn btn- ${ button . type } "> ${ button . text } </a> ` ;
} else {
btn = ` <button role="button" class="btn btn- ${ button . type } "> ${ button . text } </button> ` ;
}
footer . append ( btn ) ;
} ) ;
}
2018-10-16 16:28:42 +00:00
} ,
error : function ( data ) {
2019-01-08 21:42:54 +00:00
console . log ( data ) ;
addSnackbar ( 'warning' , '<b>Ein unbekannter Fehler ist beim Veröffentlichen deines Posts aufgetreten.</b> Bitte versuche es später erneut oder kontaktiere uns.' ) ;
2018-10-16 16:28:42 +00:00
}
} ) ;
}