]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #6577 from rabuzarus/20190129_-_jot_atachment_preview
authorHypolite Petovan <hypolite@mrpetovan.com>
Thu, 7 Feb 2019 13:43:49 +0000 (08:43 -0500)
committerGitHub <noreply@github.com>
Thu, 7 Feb 2019 13:43:49 +0000 (08:43 -0500)
Attachement live preview

mod/item.php
mod/parse_url.php
view/js/linkPreview.js [new file with mode: 0644]
view/theme/frio/css/style.css
view/theme/frio/js/jot.js [new file with mode: 0644]
view/theme/frio/js/modal.js
view/theme/frio/js/textedit.js
view/theme/frio/templates/acl_selector.tpl
view/theme/frio/templates/jot-header.tpl

index 7cb2849a89e137e54a85fbcecbb4434b2dcc47dd..40c01da20f48d5a83d489c676e2a5b30770d4a71 100644 (file)
@@ -40,6 +40,8 @@ use Friendica\Util\Emailer;
 use Friendica\Util\Security;
 use Friendica\Util\Strings;
 
+require_once 'include/items.php';
+
 function item_post(App $a) {
        if (!local_user() && !remote_user()) {
                return 0;
@@ -188,6 +190,40 @@ function item_post(App $a) {
        $categories = '';
        $postopts = '';
        $emailcc = '';
+       $body = defaults($_REQUEST, 'body', '');
+       $has_attachment = defaults($_REQUEST, 'has_attachment', 0);
+
+       // If we have a speparate attachment, we need to add it to the body.
+       if (!empty($has_attachment)) {
+               $attachment_type  = defaults($_REQUEST, 'attachment_type',  '');
+               $attachment_title = defaults($_REQUEST, 'attachment_title', '');
+               $attachment_text  = defaults($_REQUEST, 'attachment_text',  '');
+
+               $attachment_url     = hex2bin(defaults($_REQUEST, 'attachment_url',     ''));
+               $attachment_img_src = hex2bin(defaults($_REQUEST, 'attachment_img_src', ''));
+
+               $attachment_img_width  = defaults($_REQUEST, 'attachment_img_width',  0);
+               $attachment_img_height = defaults($_REQUEST, 'attachment_img_height', 0);
+               $attachment = [
+                       'type'   => $attachment_type,
+                       'title'  => $attachment_title,
+                       'text'   => $attachment_text,
+                       'url'    => $attachment_url,
+               ];
+
+               if (!empty($attachment_img_src)) {
+                       $attachment['images'] = [
+                               0 => [
+                                       'src'    => $attachment_img_src,
+                                       'width'  => $attachment_img_width,
+                                       'height' => $attachment_img_height
+                               ]
+                       ];
+               }
+
+               $att_bbcode = add_page_info_data($attachment);
+               $body .= $att_bbcode;
+       }
 
        if (!empty($orig_post)) {
                $str_group_allow   = $orig_post['allow_gid'];
@@ -201,7 +237,7 @@ function item_post(App $a) {
                $app               = $orig_post['app'];
                $categories        = $orig_post['file'];
                $title             = Strings::escapeTags(trim($_REQUEST['title']));
-               $body              = Strings::escapeHtml(trim($_REQUEST['body']));
+               $body              = Strings::escapeHtml(trim($body));
                $private           = $orig_post['private'];
                $pubmail_enabled   = $orig_post['pubmail'];
                $network           = $orig_post['network'];
@@ -237,7 +273,7 @@ function item_post(App $a) {
                $coord             = Strings::escapeTags(trim(defaults($_REQUEST, 'coord'   , '')));
                $verb              = Strings::escapeTags(trim(defaults($_REQUEST, 'verb'    , '')));
                $emailcc           = Strings::escapeTags(trim(defaults($_REQUEST, 'emailcc' , '')));
-               $body              = Strings::escapeHtml(trim(defaults($_REQUEST, 'body'    , '')));
+               $body              = Strings::escapeHtml(trim($body));
                $network           = Strings::escapeTags(trim(defaults($_REQUEST, 'network' , Protocol::DFRN)));
                $guid              = System::createUUID();
 
index b982ccf084f9e4a6b3c8caa9f0d3aa7e67e1d3d1..3b2522ab12fb05184bcd4f54f1af6a85ebbc2c00 100644 (file)
@@ -12,6 +12,7 @@
 use Friendica\App;
 use Friendica\Core\Hook;
 use Friendica\Core\Logger;
+use Friendica\Core\System;
 use Friendica\Util\Network;
 use Friendica\Util\ParseUrl;
 
@@ -19,6 +20,8 @@ function parse_url_content(App $a)
 {
        $text = null;
        $str_tags = '';
+       $format = '';
+       $ret= ['success' => false, 'contentType' => ''];
 
        $br = "\n";
 
@@ -43,6 +46,10 @@ function parse_url_content(App $a)
                }
        }
 
+       if (isset($_GET['format']) && $_GET['format'] == 'json') {
+               $format = 'json';
+       }
+
        // Add url scheme if it is missing
        $arrurl = parse_url($url);
        if (empty($arrurl['scheme'])) {
@@ -73,22 +80,35 @@ function parse_url_content(App $a)
                        }
                }
                $type = null;
+               $content_type = '';
+               $bbcode = '';
                if (array_key_exists('Content-Type', $hdrs)) {
                        $type = $hdrs['Content-Type'];
                }
                if ($type) {
                        if (stripos($type, 'image/') !== false) {
-                               echo $br . '[img]' . $url . '[/img]' . $br;
-                               exit();
+                               $content_type = 'image';
+                               $bbcode = $br . '[img]' . $url . '[/img]' . $br;
                        }
                        if (stripos($type, 'video/') !== false) {
-                               echo $br . '[video]' . $url . '[/video]' . $br;
-                               exit();
+                               $content_type = 'video';
+                               $bbcode = $br . '[video]' . $url . '[/video]' . $br;
                        }
                        if (stripos($type, 'audio/') !== false) {
-                               echo $br . '[audio]' . $url . '[/audio]' . $br;
-                               exit();
+                               $content_type = 'audio';
+                               $bbcode = $br . '[audio]' . $url . '[/audio]' . $br;
+                       }
+               }
+               if (!empty($content_type)) {
+                       if ($format == 'json') {
+                               $ret['contentType'] = $content_type;
+                               $ret['data'] = ['url' => $url];
+                               $ret['success'] = true;
+                               System::jsonExit($ret);
                        }
+
+                       echo $bbcode;
+                       exit();
                }
        }
 
@@ -130,6 +150,14 @@ function parse_url_content(App $a)
                exit();
        }
 
+       if ($format == 'json') {
+               $ret['data'] = $siteinfo;
+               $ret['contentType'] = 'attachment';
+               $ret['success'] = true;
+
+               System::jsonExit($ret);
+       }
+
        // Format it as BBCode attachment
        $info = add_page_info_data($siteinfo);
 
diff --git a/view/js/linkPreview.js b/view/js/linkPreview.js
new file mode 100644 (file)
index 0000000..ae2f0af
--- /dev/null
@@ -0,0 +1,877 @@
+/**\r
+ * Copyright (c) 2014 Leonardo Cardoso (http://leocardz.com)\r
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\r
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\r
+ * \r
+ * Restructured by Rabzuarus (https://friendica.kommune4.de/profile/rabuzarus)\r
+ * to use it in the decentralized social network Friendica (https://friendi.ca).\r
+ * \r
+ * Version: 1.4.0\r
+ */\r
+(function ($) {\r
+       $.fn.linkPreview = function (options) {\r
+               var opts = jQuery.extend({}, $.fn.linkPreview.defaults, options);\r
+\r
+               var selector = $(this).selector;\r
+               selector = selector.substr(1);\r
+\r
+               var previewTpl = '\\r
+                       <div id="preview_' + selector + '" class="preview {0}">\\r
+                               {1}\\r
+                               <input type="hidden" name="has_attachment" id="hasAttachment_' + selector + '" value="{2}" />\\r
+                               <input type="hidden" name="attachment_url" id="attachmentUrl_' + selector + '" value="{3}" />\\r
+                               <input type="hidden" name="attachment_type" id="attachmentType_' + selector + '" value="{4}" />\\r
+                       </div>';\r
+\r
+               var attachmentTpl = '\\r
+                       <hr class="previewseparator">\\r
+                       <div id="closePreview_' + selector + '" title="Remove" class="closePreview" >\\r
+                               <button type="button" class="previewActionBtn">×</button>\\r
+                       </div>\\r
+                       <div id="previewImages_' + selector + '" class="previewImages">\\r
+                               <div id="previewImgBtn_' + selector + '" class="previewImgBtn">\\r
+                                       <button type="button" id="previewChangeImg_' + selector + '" class="buttonChangeDeactive previewActionBtn" style="display: none">\\r
+                                               <i class="fa fa-exchange" aria-hidden="true"></i>\\r
+                                       </button>\\r
+                               </div>\\r
+                               <div id="previewImage_' + selector + '" class="previewImage">\\r
+                               </div>\\r
+                               <input type="hidden" id="photoNumber_' + selector + '" class="photoNumber" value="0" />\\r
+                               <input type="hidden" name="attachment_img_src" id="attachmentImageSrc_' + selector + '" value="" />\\r
+                               <input type="hidden" name="attachment_img_width" id="attachmentImageWidth_' + selector + '" value="0" />\\r
+                               <input type="hidden" name="attachment_img_height" id="attachmentImageHeight_' + selector + '" value="0" />\\r
+                       </div>\\r
+                       <div id="previewContent_' + selector + '" class="previewContent">\\r
+                               <h4 id="previewTitle_' + selector + '" class="previewTitle"></h4>\\r
+                               <blockquote id="previewDescription_' + selector + '" class="previewDescription"></blockquote>\\r
+                               <div id="hiddenDescription_' + selector + '" class="hiddenDescription"></div>\\r
+                               <sup id="previewUrl_' + selector + '" class="previewUrl"></sup>\\r
+                       </div>\\r
+                       <div class="clear"></div>\\r
+                       <hr class="previewseparator">';\r
+               var text;\r
+               var urlRegex = /(https?\:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(\/+[a-z0-9_.\:\;-]*)*(\?[\&\%\|\+a-z0-9_=,\.\:\;-]*)?([\&\%\|\+&a-z0-9_=,\:\;\.-]*)([\!\#\/\&\%\|\+a-z0-9_=,\:\;\.-]*)}*/i;\r
+               var binurl;\r
+               var block = false;\r
+               var blockTitle = false;\r
+               var blockDescription = false;\r
+               var cache = {};\r
+               var images = "";\r
+               var isExtern = false;\r
+               var photoNumber = 0;\r
+               var firstPosted = false;\r
+               var isActive = false;\r
+               var isCrawling = false;\r
+               var defaultTitle = opts.defaultTitle;\r
+               var defaultDescription = opts.defaultDescription;\r
+\r
+               /**\r
+                * Initialize the plugin\r
+                * \r
+                * @returns {void}\r
+                */\r
+               var init = function() {\r
+                       $('#' + selector).bind({\r
+                               paste: function () {\r
+                                       setTimeout(function () {\r
+                                               crawlText();\r
+                                       }, 100);\r
+                               },\r
+                               keyup: function (e) {\r
+                                       // on enter, space, ctrl\r
+                                       if ((e.which === 13 || e.which === 32 || e.which === 17)) {\r
+                                               crawlText();\r
+                                       }\r
+                               }\r
+                       });\r
+\r
+                       // Check if we have already attachment bbcode in the textarea\r
+                       // and add it to the attachment preview.\r
+                       var content = $('#' + selector).val();\r
+                       addBBCodeToPreview(content);\r
+               };\r
+\r
+               /**\r
+                * Reset some values.\r
+                * \r
+                * @returns {void}\r
+                */\r
+               var resetPreview = function() {\r
+                       $('#hasAttachment_' + selector).val(0);\r
+                       photoNumber = 0;\r
+                       images = "";\r
+               };\r
+\r
+               /**\r
+                * Crawl a text string if it contains an url and try\r
+                * to attach it.\r
+                * \r
+                * If no text is passed to crawlText() we take\r
+                * the previous word before the cursor of the textarea.\r
+                * \r
+                * @param {string} text (optional)\r
+                * @returns {void}\r
+                */\r
+               var crawlText = function (text) {\r
+                       block = false;\r
+                       images = '';\r
+                       isExtern = false;\r
+\r
+                       // If no text is passed to crawlText() we \r
+                       // take the previous word before the cursor.\r
+                       if (typeof text === 'undefined') {\r
+                               text = getPrevWord(selector);\r
+                       } else {\r
+                               isExtern = true;\r
+                       }\r
+\r
+                       // Don't procces the textarea input if we have already\r
+                       // an attachment preview.\r
+                       if (!isExtern && isActive) {\r
+                               return;\r
+                       }\r
+\r
+                       if (trim(text) !== "") {\r
+                               if (block === false && urlRegex.test(text)) {\r
+                                       binurl = bin2hex(text);\r
+                                       block = true;\r
+\r
+                                       isCrawling = true;\r
+                                       $('#profile-rotator').show();\r
+\r
+                                       if (binurl in cache) {\r
+                                               isCrawling = false;\r
+                                               processContentData(cache[binurl]);\r
+                                       } else {\r
+                                               getContentData(binurl, processContentData);\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+\r
+               /**\r
+                * Process the attachment data according to\r
+                * its content type (image, audio, video, attachment)\r
+                * \r
+                * @param {object} result\r
+                * @returns {void}\r
+                */\r
+               var processContentData = function(result) {\r
+                       if (result.contentType === 'image') {\r
+                               insertImage(result.data);\r
+                       }\r
+                       if (result.contentType === 'audio') {\r
+                               insertAudio(result.data);\r
+                       }\r
+                       if (result.contentType === 'video') {\r
+                               insertVideo(result.data);\r
+                       }\r
+                       if (result.contentType === 'attachment') {\r
+                               insertAttachment(result.data);\r
+                       }\r
+                       $('#profile-rotator').hide();\r
+               };\r
+\r
+               /**\r
+                * Fetch the content of link which should be attached.\r
+                * \r
+                * @param {string} binurl Link which should be attached as hexadecimal string.\r
+                * @param {type} callback\r
+                * @returns {void}\r
+                */\r
+               var getContentData = function(binurl, callback) {\r
+                       $.get('parse_url?binurl='+ binurl + '&format=json', function (answer) {\r
+                               obj = sanitizeInputData(answer);\r
+\r
+                               // Put the data into a cache\r
+                               cache[binurl] = obj;\r
+\r
+                               callback(obj);\r
+\r
+                               isCrawling = false;\r
+                       });\r
+               };\r
+\r
+               /*\r
+                * Add a [img] bbtag with the image url to the jot editor.\r
+                * \r
+                * @param {type} data\r
+                * @returns {void}\r
+                */\r
+               var insertImage = function(data) {\r
+                       if (!isExtern) {\r
+                               return;\r
+                       }\r
+                       var bbcode = '\n[img]' + data.url + '[/img]\n';\r
+                       addeditortext(bbcode);\r
+               };\r
+\r
+               /*\r
+                * Add a [audio] bbtag with the audio url to the jot editor.\r
+                * \r
+                * @param {type} data\r
+                * @returns {void}\r
+                */\r
+               var insertAudio = function(data) {\r
+                       if (!isExtern) {\r
+                               return;\r
+                       }\r
+                       var bbcode = '\n[audio]' + data.url + '[/audio]\n';\r
+                       addeditortext(bbcode);\r
+               };\r
+\r
+               /*\r
+                * Add a [video] bbtag with the video url to the jot editor.\r
+                * \r
+                * @param {type} data\r
+                * @returns {void}\r
+                */\r
+               var insertVideo = function(data) {\r
+                       if (!isExtern) {\r
+                               return;\r
+                       }\r
+                       var bbcode = '\n[video]' + json.url + '[/video]\n';\r
+                       addeditortext(bbcode);\r
+               };\r
+\r
+               /**\r
+                * Proccess all attachment data and show up a html\r
+                * attachment preview.\r
+                * \r
+                * @param {obj} data Attachment data.\r
+                * @returns {void}\r
+                */\r
+               var insertAttachment = function(data) {\r
+                       // If we have already a preview, leaver here.\r
+                       // Note: if we finish the Preview of other media content type,\r
+                       // we can move this condition to the beggining of crawlText();\r
+                       if (isActive) {\r
+                               $('#profile-rotator').hide();\r
+                               return;\r
+                       }\r
+\r
+                       if (data.type !== 'link' && data.type !== 'video' && data.type !== 'photo' || data.url === data.title) {\r
+                               $('#profile-rotator').hide();\r
+                               return;\r
+                       }\r
+\r
+                       $('#photoNumber_' + selector).val(0);\r
+                       resetPreview();\r
+\r
+                       processAttachmentTpl(data, 'type-' + data.type);\r
+                       addTitleDescription(data);\r
+                       addHostToAttachment(data.url);\r
+                       addImagesToAttachment(data.images);\r
+\r
+                       processEventListener();\r
+                       $('#profile-rotator').hide();\r
+               };\r
+\r
+               /**\r
+                * Construct the attachment html from the attachment template and\r
+                * add it to the DOM.\r
+                * \r
+                * @param {object} data Attachment data.\r
+                * @returns {void}\r
+                */\r
+               var processAttachmentTpl = function(data) {\r
+                       // Load and add the template if it isn't allready loaded.\r
+                       if ($('#preview_' + selector).length === 0) {\r
+                               var tpl = previewTpl.format(\r
+                                       'type-' + data.type,\r
+                                       attachmentTpl,\r
+                                       1,\r
+                                       bin2hex(data.url),\r
+                                       data.type\r
+                               );\r
+                               $('#' + selector).after(tpl);\r
+                       }\r
+\r
+                       isActive = true;\r
+               };\r
+\r
+               /**\r
+                * Add the attachment title and the description\r
+                * to the attachment preview.\r
+                * \r
+                * @param {object} data Attachment data.\r
+                * @returns {void}\r
+                */\r
+               var addTitleDescription = function(data) {\r
+                       var description = data.text;\r
+\r
+                       if (description === '') {\r
+                               description = defaultDescription;\r
+                       }\r
+\r
+                       $('#previewTitle_' + selector).html("\\r
+                               <span id='previewSpanTitle_" + selector + "' class='previewSpanTitle' >" + escapeHTML(data.title) + "</span>\\r
+                               <input type='text' name='attachment_title' value='" + escapeHTML(data.title) + "' id='previewInputTitle_" + selector + "' class='previewInputTitle inputPreview' style='display: none;'/>"\r
+                       );\r
+\r
+                       $('#previewDescription_' + selector).html("\\r
+                               <span id='previewSpanDescription_" + selector + "' class='previewSpanDescription' >" + escapeHTML(description) + "</span>\n\\r
+                               <textarea id='previewInputDescription_" + selector + "' name='attachment_text' class='previewInputDescription' style='display: none;' class='inputPreview' >" + escapeHTML(data.text) + "</textarea>"\r
+                       );\r
+               };\r
+\r
+               /**\r
+                * Add the host to the attachment preview.\r
+                * \r
+                * @param {string} url The url of the link attachment.\r
+                * @returns {void}\r
+                */\r
+               var addHostToAttachment = function(url) {\r
+                       if (url) {\r
+                               var regexpr = "(https?://)([^:^/]*)(:\\d*)?(.*)?";\r
+                               var regResult = url.match(regexpr);\r
+                               var urlHost = regResult[1] + regResult[2];\r
+                               $('#previewUrl_' + selector).html("<a href='" + url + "'>" + urlHost + "</a>");\r
+                       }\r
+               };\r
+\r
+               /**\r
+                * Add preview images to the attachment.\r
+                * \r
+                * @param {array} images\r
+                * \r
+                * @returns {void}\r
+                */\r
+               var addImagesToAttachment = function(images) {\r
+                       var imageClass = 'attachment-preview';\r
+       \r
+                       if (Array.isArray(images)) {\r
+                               $('#previewImages_' + selector).show();\r
+                               $('#attachmentImageSrc_' + selector).val(bin2hex(images[photoNumber].src));\r
+                               $('#attachmentImageWidth_' + selector).val(images[photoNumber].width);\r
+                               $('#attachmentImageHeight_' + selector).val(images[photoNumber].height);\r
+                       } else {\r
+                               $('#previewImages_' + selector).hide();\r
+                       }\r
+\r
+                       images.length = parseInt(images.length);\r
+                       var appendImage = "";\r
+\r
+                       for (i = 0; i < images.length; i++) {\r
+                               // For small preview images we use a smaller attachment format.\r
+                               ///@todo here we need to add a check for !Config::get('system', 'always_show_preview').\r
+                               if (images[i].width >= 500 && images[i].width >= images[i].height) {\r
+                                               imageClass = 'attachment-image';\r
+                               }\r
+\r
+                               if (i === 0) {\r
+                                       appendImage += "<img id='imagePreview_" + selector + "_" + i + "' src='" + images[i].src + "' class='" + imageClass + "' ></img>";\r
+                               } else {\r
+                                       appendImage += "<img id='imagePreview_" + selector + "_" + i + "' src='" + images[i].src + "' class='" + imageClass + "' style='display: none;'></img>";\r
+                               }\r
+                       }\r
+\r
+                       $('#previewImage_' + selector).html(appendImage + "<div id='whiteImage' style='color: transparent; display:none;'>...</div>");\r
+\r
+                       // More than just one image.\r
+                       if (images.length > 1) {\r
+                               // Enable the the button to change the preview pictures.\r
+                               $('#previewChangeImg_' + selector).show();\r
+\r
+                               if (firstPosted === false) {\r
+                                       firstPosted = true;\r
+\r
+                                       $('#previewChangeImg_' + selector).unbind('click').click(function (e) {\r
+                                               e.stopPropagation();\r
+                                               if (images.length > 1) {\r
+                                                       $('#imagePreview_' + selector + '_' + photoNumber).css({\r
+                                                               'display': 'none'\r
+                                                       });\r
+                                                       photoNumber += 1;\r
+\r
+                                                       // If have reached the last image, begin with the first image.\r
+                                                       if (photoNumber === images.length) {\r
+                                                               photoNumber = 0;\r
+                                                       }\r
+\r
+                                                       $('#imagePreview_' + selector + '_' + photoNumber).css({\r
+                                                               'display': 'block'\r
+                                                       });\r
+                                                       $('#photoNumber_' + selector).val(photoNumber);\r
+                                                       $('#attachmentImageSrc_' + selector).val(bin2hex(images[photoNumber].src));\r
+                                                       $('#attachmentImageWidth_' + selector).val(images[photoNumber].width);\r
+                                                       $('#attachmentImageHeight_' + selector).val(images[photoNumber].height);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       }\r
+               };\r
+\r
+               /**\r
+                * Add event listener to control the attachment preview.\r
+                * \r
+                * @returns {void}\r
+                */\r
+               var processEventListener = function() {\r
+                       $('#previewSpanTitle_' + selector).unbind('click').click(function (e) {\r
+                               e.stopPropagation();\r
+                               if (blockTitle === false) {\r
+                                       blockTitle = true;\r
+                                       $('#previewSpanTitle_' + selector).hide();\r
+                                       $('#previewInputTitle_' + selector).show();\r
+                                       $('#previewInputTitle_' + selector).val($('#previewInputTitle_' + selector).val());\r
+                                       $('#previewInputTitle_' + selector).focus().select();\r
+                               }\r
+                       });\r
+\r
+                       $('#previewInputTitle_' + selector).blur(function () {\r
+                               blockTitle = false;\r
+                               $('#previewSpanTitle_' + selector).html($('#previewInputTitle_' + selector).val());\r
+                               $('#previewSpanTitle_' + selector).show();\r
+                               $('#previewInputTitle_' + selector).hide();\r
+                       });\r
+\r
+                       $('#previewInputTitle_' + selector).keypress(function (e) {\r
+                               if (e.which === 13) {\r
+                                       blockTitle = false;\r
+                                       $('#previewSpanTitle_' + selector).html($('#previewInputTitle_' + selector).val());\r
+                                       $('#previewSpanTitle_' + selector).show();\r
+                                       $('#previewInputTitle_' + selector).hide();\r
+                               }\r
+                       });\r
+\r
+                       $('#previewSpanDescription_' + selector).unbind('click').click(function (e) {\r
+                               e.stopPropagation();\r
+                               if (blockDescription === false) {\r
+                                       blockDescription = true;\r
+                                       $('#previewSpanDescription_' + selector).hide();\r
+                                       $('#previewInputDescription_' + selector).show();\r
+                                       $('#previewInputDescription_' + selector).val($('#previewInputDescription_' + selector).val());\r
+                                       $('#previewInputDescription_' + selector).focus().select();\r
+                               }\r
+                       });\r
+\r
+                       $('#previewInputDescription_' + selector).blur(function () {\r
+                               blockDescription = false;\r
+                               $('#previewSpanDescription_' + selector).html($('#previewInputDescription_' + selector).val());\r
+                               $('#previewSpanDescription_' + selector).show();\r
+                               $('#previewInputDescription_' + selector).hide();\r
+                       });\r
+\r
+                       $('#previewInputDescription_' + selector).keypress(function (e) {\r
+                               if (e.which === 13) {\r
+                                       blockDescription = false;\r
+                                       $('#previewSpanDescription_' + selector).html($('#previewInputDescription_' + selector).val());\r
+                                       $('#previewSpanDescription_' + selector).show();\r
+                                       $('#previewInputDescription_' + selector).hide();\r
+                               }\r
+                       });\r
+\r
+                       $('#previewSpanTitle_' + selector).mouseover(function () {\r
+                               $('#previewSpanTitle_' + selector).css({\r
+                                       "background-color": "#ff9"\r
+                               });\r
+                       });\r
+\r
+                       $('#previewSpanTitle_' + selector).mouseout(function () {\r
+                               $('#previewSpanTitle_' + selector).css({\r
+                                       "background-color": "transparent"\r
+                               });\r
+                       });\r
+\r
+                       $('#previewSpanDescription_' + selector).mouseover(function () {\r
+                               $('#previewSpanDescription_' + selector).css({\r
+                                       "background-color": "#ff9"\r
+                               });\r
+                       });\r
+\r
+                       $('#previewSpanDescription_' + selector).mouseout(function () {\r
+                               $('#previewSpanDescription_' + selector).css({\r
+                                       "background-color": "transparent"\r
+                               });\r
+                       });\r
+\r
+                       $('#closePreview_' + selector).unbind('click').click(function (e) {\r
+                               e.stopPropagation();\r
+                               block = false;\r
+                               images = '';\r
+                               isActive = false;\r
+                               firstPosted = false;\r
+                               $('#preview_' + selector).fadeOut("fast", function () {\r
+                                       $('#preview_' + selector).remove();\r
+                                       $('#profile-rotator').hide();\r
+                                       $('#' + selector).focus();\r
+                               });\r
+\r
+                       });\r
+               };\r
+\r
+               /**\r
+                * Convert attachmant bbcode into an array.\r
+                * \r
+                * @param {string} content Text content with the attachment bbcode.\r
+                * @returns {object || null}\r
+                */\r
+               var getAttachmentData = function(content) {\r
+                       var data = {};\r
+\r
+                       var match = content.match(/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism);\r
+                       if (match === null || match.length < 5) {\r
+                               return null;\r
+                       }\r
+\r
+                       var attributes = match[2];\r
+                       data.text = trim(match[1]);\r
+\r
+                       var type = '';\r
+                       var matches = attributes.match(/type='(.*?)'/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               type = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       matches = attributes.match(/type="(.*?)"/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               type = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       if (type === '') {\r
+                               return null;\r
+                       }\r
+\r
+                       if (\r
+                               type !== 'link'\r
+                               && type !== 'audio'\r
+                               && type !== 'photo'\r
+                               && type !== 'video')\r
+                       {\r
+                               return null;\r
+                       }\r
+\r
+                       if (type !== '') {\r
+                               data.type = type;\r
+                       }\r
+\r
+                       var url = '';\r
+\r
+                       matches = attributes.match(/url='(.*?)'/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               url = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       matches = attributes.match(/url="(.*?)"/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               url = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       if(url !== '') {\r
+                               data.url = escapeHTML(url);\r
+                       }\r
+\r
+                       var title = '';\r
+\r
+                       matches = attributes.match(/title='(.*?)'/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               title = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       matches = attributes.match(/title="(.*?)"/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               title = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       if (title !== '') {\r
+                               data.title = escapeHTML(title);\r
+                       }\r
+\r
+                       var image = '';\r
+\r
+                       matches = attributes.match(/image='(.*?)'/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               image = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       matches = attributes.match(/image="(.*?)"/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               image = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       if (image !== '') {\r
+                               data.image = escapeHTML(image);\r
+                       }\r
+\r
+                       var preview = '';\r
+\r
+                       matches = attributes.match(/preview='(.*?)'/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               preview = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       matches = attributes.match(/preview="(.*?)"/ism);\r
+                       if (matches !== null && typeof matches[1] !== 'undefined') {\r
+                               preview = matches[1].toLowerCase();\r
+                       }\r
+\r
+                       if (preview !== '') {\r
+                               data.preview = escapeHTML(preview);\r
+                       }\r
+\r
+                       data.text = trim(match[3]);\r
+                       data.after = trim(match[4]);\r
+\r
+                       return data;\r
+               };\r
+\r
+               /**\r
+                * Process txt content and if it contains attachment bbcode\r
+                * add it to the attachment preview .\r
+                * \r
+                * @param {string} content\r
+                * @returns {void}\r
+                */\r
+               var addBBCodeToPreview =function(content) {\r
+                       var attachmentData = getAttachmentData(content);\r
+                       if (attachmentData) {\r
+                               reAddAttachment(attachmentData);\r
+                               // Remove the attachment bbcode from the textarea.\r
+                               var content = content.replace(/\[attachment.*\[\/attachment]/ism, '');\r
+                               $('#' + selector).val(content);\r
+                               $('#' + selector).focus();\r
+                       }\r
+               };\r
+\r
+               /**\r
+                * Add an Attachment with data from an old bbcode\r
+                * generated attachment.\r
+                * \r
+                * @param {object} json The attachment data.\r
+                * @returns {void}\r
+                */\r
+               var reAddAttachment = function(json) {\r
+                       if (isActive) {\r
+                               $('#profile-rotator').hide();\r
+                               return;\r
+                       }\r
+\r
+                       if (json.type !== 'link' && json.type !== 'video' && json.type !== 'photo' || json.url === json.title) {\r
+                               $('#profile-rotator').hide();\r
+                               return;\r
+                       }\r
+\r
+                       var obj = {data: json};\r
+                       obj = sanitizeInputData(obj);\r
+\r
+                       var data = obj.data;\r
+\r
+                       resetPreview();\r
+\r
+                       processAttachmentTpl(data);\r
+                       addTitleDescription(data);\r
+                       addHostToAttachment(data.url);\r
+\r
+                       // Since we don't have an array of image data,\r
+                       // we need to add the preview images in a different way\r
+                       // than in function addImagesToAttachment().\r
+                       var imageClass = 'attachment-preview';\r
+                       var image = '';\r
+\r
+                       if (data.image !== '') {\r
+                               imageClass = 'attachment-image';\r
+                               image = data.image;\r
+                       } else {\r
+                               image = data.preview;\r
+                       }\r
+\r
+                       if (image !== '') {\r
+                               var appendImage = "<img id='imagePreview_" + selector + "' src='" + image + "' class='" + imageClass + "' ></img>"\r
+                               $('#previewImage_' + selector).html(appendImage);\r
+                               $('#attachmentImageSrc_' + selector).val(bin2hex(image));\r
+\r
+                               // We need to add the image widht and height when it is \r
+                               // loaded.\r
+                               $('<img/>' ,{\r
+                                       load : function(){\r
+                                               $('#attachmentImageWidth_' + selector).val(this.width);\r
+                                               $('#attachmentImageHeight_' + selector).val(this.height);\r
+                                       },\r
+                                       src  : image\r
+                               });\r
+                       }\r
+\r
+                       processEventListener();\r
+                       $('#profile-rotator').hide();\r
+               };\r
+\r
+               /**\r
+                * Add missing default properties to the input data object.\r
+                * \r
+                * @param {object} obj Input data.\r
+                * @returns {object}\r
+                */\r
+               var sanitizeInputData = function(obj) {\r
+                       if (typeof obj.contentType === 'undefined'\r
+                               || obj.contentType === null)\r
+                       {\r
+                               obj.contentType = "";\r
+                       }\r
+                       if (typeof obj.data.url === 'undefined'\r
+                               || obj.data.url === null)\r
+                       {\r
+                               obj.data.url = "";\r
+                       }\r
+                       if (typeof obj.data.title === 'undefined'\r
+                               || obj.data.title === null\r
+                               || obj.data.title === "")\r
+                       {\r
+                               obj.data.title = defaultTitle;\r
+                       }\r
+                       if (typeof obj.data.text === 'undefined'\r
+                               || obj.data.text === null\r
+                               || obj.data.text === "")\r
+                       {\r
+                               obj.data.text = "";\r
+                       }\r
+                       if (typeof obj.data.images === 'undefined'\r
+                               || obj.data.images === null)\r
+                       {\r
+                               obj.data.images = "";\r
+                       }\r
+\r
+                       if (typeof obj.data.image === 'undefined'\r
+                               || obj.data.image === null)\r
+                       {\r
+                               obj.data.image = "";\r
+                       }\r
+\r
+                       if (typeof obj.data.preview === 'undefined'\r
+                               || obj.data.preview === null)\r
+                       {\r
+                               obj.data.preview = "";\r
+                       }\r
+\r
+                       return obj;\r
+               };\r
+\r
+               /**\r
+                * Destroy the plugin.\r
+                * \r
+                * @returns {void}\r
+                */\r
+               var destroy = function() {\r
+                       $('#' + selector).unbind();\r
+                       $('#preview_' + selector).remove();\r
+                       binurl;\r
+                       block = false;\r
+                       blockTitle = false;\r
+                       blockDescription = false;\r
+                       cache = {};\r
+                       images = "";\r
+                       isExtern = false;\r
+                       photoNumber = 0;\r
+                       firstPosted = false;\r
+                       isActive = false;\r
+                       isCrawling = false;\r
+                       selector = "";\r
+               };\r
+\r
+               var trim = function(str) {\r
+                       return str.replace(/^\s+|\s+$/g, "");\r
+               };\r
+               var escapeHTML = function(unsafe_str) {\r
+                       return unsafe_str\r
+                               .replace(/&/g, '&amp;')\r
+                               .replace(/</g, '&lt;')\r
+                               .replace(/>/g, '&gt;')\r
+                               .replace(/\"/g, '&quot;')\r
+                               .replace(/\[/g, '&#91;')\r
+                               .replace(/\]/g, '&#93;')\r
+                               .replace(/\'/g, '&#39;'); // '&apos;' is not valid HTML 4\r
+               };\r
+\r
+               // Initialize LinkPreview \r
+               init();\r
+\r
+               return {\r
+                       // make crawlText() accessable from the outside.\r
+                       crawlText: function(text) {\r
+                               crawlText(text);\r
+                       },\r
+                       addBBCodeToPreview: function(content) {\r
+                               addBBCodeToPreview(content);\r
+                       },\r
+                       destroy: function() {\r
+                               destroy();\r
+                       }\r
+               };\r
+       };\r
+\r
+       $.fn.linkPreview.defaults = {\r
+               defaultDescription: "Enter a description",\r
+               defaultTitle: "Enter a title"\r
+       };\r
+\r
+       /**\r
+       * Get in a textarea the previous word before the cursor.\r
+       * \r
+       * @param {object} text Textarea elemet.\r
+       * @param {integer} caretPos Cursor position.\r
+       * \r
+       * @returns {string} Previous word.\r
+       */\r
+       function returnWord(text, caretPos) {\r
+               var index = text.indexOf(caretPos);\r
+               var preText = text.substring(0, caretPos);\r
+               // If the last charachter is a space or enter remove it\r
+               // We need this in friendica for the url  preview.\r
+               var lastChar = preText.slice(-1)\r
+               if ( lastChar === " "\r
+                       || lastChar === "\n"\r
+                       || lastChar === "\r"\r
+                       )\r
+               {\r
+                       preText = preText.substring(0, preText.length -1);\r
+               }\r
+\r
+               // Replace new line with space.\r
+               preText = preText.replace(/\n/g, " ");\r
+\r
+               if (preText.indexOf(" ") > 0) {\r
+                       var words = preText.split(" ");\r
+                       return words[words.length - 1]; //return last word\r
+               }\r
+               else {\r
+                       return preText;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get in a textarea the previous word before the cursor.\r
+        * \r
+        * @param {string} id The ID of a textarea element.\r
+        * @returns {sting|null} Previous word or null if no word is available.\r
+        */\r
+       function getPrevWord(id) {\r
+               var text = document.getElementById(id);\r
+               var caretPos = getCaretPosition(text);\r
+               var word = returnWord(text.value, caretPos);\r
+               if (word != null) {\r
+                       return word\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Get the cursor posiotion in an text element.\r
+        * \r
+        * @param {object} ctrl Textarea elemet.\r
+        * @returns {integer} Position of the cursor.\r
+        */\r
+       function getCaretPosition(ctrl) {\r
+               var CaretPos = 0;   // IE Support\r
+               if (document.selection) {\r
+                       ctrl.focus();\r
+                       var Sel = document.selection.createRange();\r
+                       Sel.moveStart('character', -ctrl.value.length);\r
+                       CaretPos = Sel.text.length;\r
+               }\r
+               // Firefox support\r
+               else if (ctrl.selectionStart || ctrl.selectionStart == '0') {\r
+                       CaretPos = ctrl.selectionStart;\r
+               }\r
+               return (CaretPos);\r
+       }\r
+})(jQuery);\r
index d45d7c47a92624d105042ca8fd7adabf98356e72..c2ad62d3c3eec05dfbf9b8c26a3463bc77ee4e8f 100644 (file)
@@ -1326,6 +1326,29 @@ section #jotOpen {
 .jothidden {
     /*display: none;*/
 }
+.modal #jot-sections {
+    max-height: calc(100vh - 22px);
+}
+@media (min-width: 768px) {
+    .modal #jot-sections {
+        max-height: calc(100vh - 62px);
+    }
+}
+#jot-modal #jot-sections,
+#jot-modal #jot-modal-body,
+#jot-modal #profile-jot-form,
+#jot-modal #profile-jot-wrapper,
+#jot-modal #jot-text-wrap,
+#jot-modal #jot-preview-content,
+#jot-modal #tread-wrapper--1,
+#jot-modal #item-Q0,
+#jot-modal #profile-jot-acl-wrapper,
+#jot-modal #acl-wrapper {
+    overflow: hidden;
+    display: flex;
+    flex: auto;
+    flex-direction: column;
+}
 #jot-modal .modal-header a, #jot-modal .modal-header .btn-link,
 #profile-jot-submit-wrapper a, #profile-jot-submit-wrapper .btn-link {
     color: #555;
@@ -1342,6 +1365,69 @@ section #jotOpen {
 }
 #jot-text-wrap textarea {
     min-height: 100px;
+    overflow-y: auto !important;
+    overflow-y: overlay !important;
+}
+/*#jot-attachment-preview {
+    display: none;
+}*/
+#jot-text-wrap .preview textarea {
+    width: 100%;
+}
+#preview_profile-jot-text {
+    position: relative;
+    padding: 0px 10px;
+    margin-top: -2px;
+    border: 2px solid #ededed;
+    border-top: none;
+    box-shadow: none;
+    border-radius: 0 0 4px 4px;
+    background: #fff;
+    color: #555;
+}
+textarea#profile-jot-text:focus + #preview_profile-jot-text {
+    border: 2px solid #6fdbe8;
+    border-top: none;
+}
+.preview hr.previewseparator {
+    margin-top: 0px;
+    border-color: #D2D2D2;
+}
+#previewImgBtn_profile-jot-text,
+.closePreview  {
+    position: absolute;
+    top: 15px;
+}
+.closePreview {
+    right: 15px;
+    z-index: 1;
+}
+.previewImgBtn {
+    left: 15px;
+}
+.preview button.previewActionBtn {
+    display:block;
+    height: 25px;
+    width: 25px;
+    border-radius: 50%;
+    color: #fff;
+    border: 2px solid #fff;
+    box-shadow: 0 0 3px gray;
+    background: #777;
+    text-align: center;
+    line-height: 2px;
+    text-decoration: none;
+    padding: 0 0 1px 1px;
+    opacity: 0.7;
+}
+.preview button.previewActionBtn:hover {
+    opacity: 1;
+}
+.preview .closePreview button.previewActionBtn {
+    font-size: 25px;
+}
+#previewInputTitle_profile-jot-text {
+    width: 100%;
 }
 #profile-jot-wrapper button#profile-jot-submit {
     margin-top: 5px;
@@ -1349,7 +1435,10 @@ section #jotOpen {
 #profile-jot-wrapper #character-counter {
     padding: 10px 15px;
 }
-
+.modal .wall-item-container.preview {
+    overflow-y: auto;
+    overflow-y: overlay;
+}
 /* ACL */
 /*#jot-modal-body {
     height: auto;
@@ -1357,7 +1446,7 @@ section #jotOpen {
     overflow-y: hidden;
 }*/
 #acl-search {
-    margin-top: 20px;
+    /*margin-top: 20px;*/
     /*padding: 8px;*/
     /*border: 1px solid #ccc;*/
     width: 100%;
@@ -1365,7 +1454,6 @@ section #jotOpen {
 #acl-list {
     display: block;
     border: 1px solid #ccc;
-    overflow: auto;
     clear: both;
     min-height: 62px;
     margin-top: 20px;
@@ -1373,10 +1461,10 @@ section #jotOpen {
     -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
     border-radius: 4px;
+    overflow-y: auto;
 }
 #acl-list-content {
-    overflow-y: auto;
-    max-height: calc(100vh - 330px);
+    overflow-y: hidden;
     height: auto !important;
 }
 .acl-list-item {
diff --git a/view/theme/frio/js/jot.js b/view/theme/frio/js/jot.js
new file mode 100644 (file)
index 0000000..d55e509
--- /dev/null
@@ -0,0 +1,39 @@
+// We append the linkPreview to a global Variable to make linkPreview
+// accessable on other places. Note: search on other places before you
+// delete or move the variable.
+var linkPreview;
+
+/**
+ * Insert a link into friendica jot.
+ * 
+ * @returns {void}
+ */
+function jotGetLink() {
+       var currentText = $("#profile-jot-text").val();
+       var noAttachment = '';
+       reply = prompt(aStr.linkurl);
+       if(reply && reply.length) {
+               // There should be only one attachment per post.
+               // So we need to remove the old one.
+               $('#jot-attachment-preview').empty();
+               $('#profile-rotator').show();
+               if (currentText.includes("[attachment") && currentText.includes("[/attachment]")) {
+                       noAttachment = '&noAttachment=1';
+               }
+
+               // We use the linkPreview library to have a preview
+               // of the attachments.
+               if (typeof linkPreview === 'object') {
+                       linkPreview.crawlText(reply + noAttachment);
+
+               // Fallback: insert the attachment bbcode directly into the textarea
+               // if the attachment live preview isn't available
+               } else {
+                       $.get('parse_url?binurl=' + bin2hex(reply) + noAttachment, function(data) {
+                               addeditortext(data);
+                               $('#profile-rotator').hide();
+                       });
+               }
+               autosize.update($("#profile-jot-text"));
+       }
+}
index 80694b64da52971d890adf9be0fa130975b15b0d..1c5314c4b410b6052a86830b44e867ffe01dddaf 100644 (file)
@@ -22,6 +22,10 @@ $(document).ready(function(){
                $("#jot-content").append(jotcache);
                // Clear the jotcache.
                jotcache = '';
+               // Destroy the attachment linkPreviw for Jot.
+               if (typeof linkPreview === 'object') {
+                       linkPreview.destroy();
+               }
        });
 
        // Add Colorbox for viewing Network page images.
@@ -292,6 +296,7 @@ function editpost(url) {
 
                                modal.show();
                                $("#jot-popup").show();
+                               linkPreview = $('#profile-jot-text').linkPreview();
                        }
                });
 }
index 76a04a32f2887b49913c6e80bed291184c692881..e0c06af581f134ce8a7e9750beab82d0c0488336 100644 (file)
@@ -46,34 +46,34 @@ function commentGetLink(id, prompttext) {
 }
 
 function addCommentText(data, id) {
-    // get the textfield
-    var textfield = document.getElementById("comment-edit-text-" + id);
-    // check if the textfield does have the default-value
-    commentOpenUI(textfield, id);
-    // save already existent content
-    var currentText = $("#comment-edit-text-" + id).val();
-    //insert the data as new value
-    textfield.value = currentText + data;
-    autosize.update($("#comment-edit-text-" + id));
+       // get the textfield
+       var textfield = document.getElementById("comment-edit-text-" + id);
+       // check if the textfield does have the default-value
+       commentOpenUI(textfield, id);
+       // save already existent content
+       var currentText = $("#comment-edit-text-" + id).val();
+       //insert the data as new value
+       textfield.value = currentText + data;
+       autosize.update($("#comment-edit-text-" + id));
 }
 
 function commentLinkDrop(event, id) {
-    var reply = event.dataTransfer.getData("text/uri-list");
-    event.target.textContent = reply;
-    event.preventDefault();
-    if (reply && reply.length) {
-        reply = bin2hex(reply);
-        $.get('parse_url?noAttachment=1&binurl=' + reply, function(data) {
+       var reply = event.dataTransfer.getData("text/uri-list");
+       event.target.textContent = reply;
+       event.preventDefault();
+       if (reply && reply.length) {
+               reply = bin2hex(reply);
+               $.get('parse_url?noAttachment=1&binurl=' + reply, function(data) {
                        addCommentText(data, id);
-        });
-    }
+               });
+       }
 }
 
 function commentLinkDropper(event) {
-    var linkFound = event.dataTransfer.types.contains("text/uri-list");
-    if (linkFound) {
-        event.preventDefault();
-    }
+       var linkFound = event.dataTransfer.types.contains("text/uri-list");
+       if (linkFound) {
+               event.preventDefault();
+       }
 }
 
 
index 6a9e38eb37168bef2023537fb6839e8992991240..49a7226eca31c752ad3196ee96975d04223f4556 100644 (file)
@@ -1,6 +1,8 @@
 
 <div id="acl-wrapper">
-       <button id="acl-showall" class="btn btn-block btn-default"><i class="fa fa-globe"></i> {{$showall}}</button>
+       <div class="form-group form-group-search">
+               <button id="acl-showall" class="btn btn-block btn-default"><i class="fa fa-globe"></i> {{$showall}}</button>
+       </div>
        <div class="form-group form-group-search">
                <input type="text" id="acl-search" class="form-control form-search">
        </div>
index 70370e42eba3049a5248d10695b2323973376602..ac59caed8e16dd18ff32052ce925088d41caed70 100644 (file)
@@ -1,5 +1,7 @@
 
-<script type="text/javascript" src="{{$baseurl}}/view/js/ajaxupload.js" ></script>
+<script type="text/javascript" src="{{$baseurl}}/view/js/ajaxupload.js"></script>
+<script type="text/javascript" src="{{$baseurl}}/view/js/linkPreview.js"></script>
+<script type="text/javascript" src="{{$baseurl}}/view/theme/frio/js/jot.js"></script>
 
 <script type="text/javascript">
        var editor = false;
@@ -39,6 +41,7 @@
 
 <script type="text/javascript">
        var ispublic = '{{$ispublic}}';
+       aStr.linkurl = '{{$linkurl}}';
 
 
        $(document).ready(function() {
                }
        }
 
-       function jotGetLink() {
-               var currentText = $("#profile-jot-text").val();
-               var noAttachment = '';
-               reply = prompt("{{$linkurl}}");
-               if(reply && reply.length) {
-                       reply = bin2hex(reply);
-                       $('#profile-rotator').show();
-                       if (currentText.includes("[attachment") && currentText.includes("[/attachment]")) {
-                               noAttachment = '&noAttachment=1';
-                       }
-                       $.get('parse_url?binurl=' + reply + noAttachment, function(data) {
-                               addeditortext(data);
-                               $('#profile-rotator').hide();
-                       });
-                       autosize.update($("#profile-jot-text"));
-               }
-       }
-
        function jotVideoURL() {
                reply = prompt("{{$vidurl}}");
                if(reply && reply.length) {
                }
        }
 
-
        function jotGetLocation() {
                reply = prompt("{{$whereareu}}", $('#jot-location').val());
                if(reply && reply.length) {
        }
 
        function itemFiler(id) {
-
                var bordercolor = $("input").css("border-color");
 
                $.get('filer/', function(data){
                        .find('#jot-modal-content')
                        .append(jotcache)
                        .modal.show;
+
+               // Jot attachment live preview.
+               linkPreview = $('#profile-jot-text').linkPreview();
        }
 
        // Activate the jot text section in the jot modal