This commit is contained in:
Habeas Codice 2015-01-21 21:27:07 -08:00
commit c05f0ec407
17 changed files with 184 additions and 89 deletions

View File

@ -83,7 +83,9 @@ $DIRECTORY_FALLBACK_SERVERS = array(
'https://zotid.net',
'https://red.zottel.red',
'https://red.pixelbits.de',
'https://whogotzot.com'
'https://my.federated.social',
'https://whogotzot.com',
'https://redmatrix.nl'
);
@ -500,7 +502,6 @@ define ( 'ACTIVITY_FAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'favorite' );
define ( 'ACTIVITY_POKE', NAMESPACE_ZOT . '/activity/poke' );
define ( 'ACTIVITY_MOOD', NAMESPACE_ZOT . '/activity/mood' );
define ( 'ACTIVITY_FILE', NAMESPACE_ZOT . '/activity/file' );
define ( 'ACTIVITY_OBJ_COMMENT', NAMESPACE_ACTIVITY_SCHEMA . 'comment' );
define ( 'ACTIVITY_OBJ_NOTE', NAMESPACE_ACTIVITY_SCHEMA . 'note' );
@ -514,6 +515,7 @@ define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_ZOT . '/activity/tagterm' );
define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_ZOT . '/activity/profile' );
define ( 'ACTIVITY_OBJ_THING', NAMESPACE_ZOT . '/activity/thing' );
define ( 'ACTIVITY_OBJ_LOCATION',NAMESPACE_ZOT . '/activity/location' );
define ( 'ACTIVITY_OBJ_FILE', NAMESPACE_ZOT . '/activity/file' );
/**
* item weight for query ordering

View File

@ -2,6 +2,9 @@
Roadmap for Redmatrix V3
Crypto
Convert E2EE to dynamic loading (on demand) using jQuery.getScript() [or other methods] to only load encryption libs when you require them. This should also support multiple encryption libraries (e.g. SJCL, others) triggered from the choice of algorithm and remain pluggable.
Subscriptions and business models
Build enough into core(/addons) to generate income (or at least try and cover costs) out of the box

View File

@ -753,7 +753,7 @@ function attach_delete($channel_id, $resource) {
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
$r = q("SELECT hash, filename, flags, folder FROM attach WHERE hash = '%s' AND uid = %d limit 1",
$r = q("SELECT hash, flags, folder FROM attach WHERE hash = '%s' AND uid = %d limit 1",
dbesc($resource),
intval($channel_id)
);
@ -762,8 +762,6 @@ function attach_delete($channel_id, $resource) {
if(! $r)
return;
$url = get_parent_cloudpath($channel_id, $channel_address, $resource) . $r[0]['filename'];
// If resource is a directory delete everything in the directory recursive
if($r[0]['flags'] & ATTACH_FLAG_DIR) {
$x = q("SELECT hash, flags FROM attach WHERE folder = '%s' AND uid = %d",
@ -806,7 +804,7 @@ function attach_delete($channel_id, $resource) {
intval($channel_id)
);
file_activity($channel_id, $resource, $allow_cid='', $allow_gid='', $deny_cid='', $deny_gid='', $url, 'drop', $no_activity=false);
file_activity($channel_id, $resource, $cloudpath='', $allow_cid='', $allow_gid='', $deny_cid='', $deny_gid='', 'drop', $no_activity=false);
}
/**
@ -942,32 +940,77 @@ function pipe_streams($in, $out) {
return $size;
}
function file_activity($channel_id, $hash, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $url, $action, $no_activity) {
function file_activity($channel_id, $hash, $cloudpath, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $no_activity) {
require_once('include/items.php');
$url = rawurlencode($url);
$poster = get_app()->get_observer();
$verb = ACTIVITY_FILE . '/' . $action . '/' . $hash;
switch($verb) {
case 'post':
$activity = ACTIVITY_POST;
$x = q("SELECT creator, filename, filetype, filesize, revision, folder, flags, created, edited FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($hash)
);
break;
case 'drop':
$activity = ACTIVITY_UPDATE;
break;
default:
return;
break;
}
$url = (($cloudpath && $x[0]['filename']) ? rawurlencode($cloudpath . $x[0]['filename']) : 'unavailable');
$mid = item_message_id();
$item_flags = ITEM_WALL|ITEM_ORIGIN|ITEM_UNSEEN;
if($action == 'post') {
//check if activity item exists
//if yes send drop activity and create a new one
$links = array();
$links[] = array(
'rel' => 'alternate',
'type' => 'text/html',
'href' => $url
);
$r = q("SELECT * FROM item WHERE verb = '%s'",
dbesc($verb)
$objtype = ACTIVITY_OBJ_FILE;
$object = array(
'type' => ACTIVITY_OBJ_FILE,
'title' => (($x[0]['filename']) ? $x[0]['filename'] : 'unavailable'),
'id' => $url,
'link' => $links,
'hash' => $hash,
'creator' => (($x[0]['creator']) ? $x[0]['creator'] : ''),
'filename' => (($x[0]['filename']) ? $x[0]['filename'] : ''),
'filetype' => (($x[0]['filetype']) ? $x[0]['filetype'] : ''),
'filesize' => (($x[0]['filesize']) ? $x[0]['filesize'] : ''),
'revision' => (($x[0]['revision']) ? $x[0]['revision'] : ''),
'folder' => (($x[0]['folder']) ? $x[0]['folder'] : ''),
'flags' => (($x[0]['flags']) ? $x[0]['flags'] : ''),
'created' => (($x[0]['created']) ? $x[0]['created'] : ''),
'edited' => (($x[0]['edited']) ? $x[0]['edited'] : '')
);
$private = (($allow_cid || $allow_gid || $deny_cid || $deny_gid) ? 1 : 0);
if($verb == 'post') {
//check if activity item exists
//if yes send update (drop) activity and create a new one
$y = q("SELECT * FROM item WHERE verb = '%s' AND obj_type = '%s' AND object LIKE '%s'",
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_OBJ_FILE),
dbesc('%"hash":"' . $hash . '"%')
);
if($r) {
if($y) {
$dmid = item_message_id();
$updateverb = ACTIVITY_FILE . '/drop/' . $hash . '#' . $mid;
$object['mid'] = $mid; //attach mid for update object
$arr = array();
@ -979,14 +1022,17 @@ function file_activity($channel_id, $hash, $allow_cid, $allow_gid, $deny_cid, $d
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
$arr['allow_cid'] = $allow_cid;
$arr['allow_gid'] = $allow_gid;
$arr['deny_cid'] = $deny_cid;
$arr['deny_gid'] = $deny_gid;
//updates must be visible to everybody -> perms may have changed
$arr['allow_cid'] = '';
$arr['allow_gid'] = '';
$arr['deny_cid'] = '';
$arr['deny_gid'] = '';
$arr['item_restrict'] = ITEM_HIDDEN;
$arr['item_private'] = 0;
$arr['verb'] = $updateverb;
$arr['body'] = $url;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = $objtype;
$arr['object'] = json_encode($object);
$arr['body'] = '';
$post = item_store($arr);
$item_id = $post['item_id'];
@ -995,7 +1041,9 @@ function file_activity($channel_id, $hash, $allow_cid, $allow_gid, $deny_cid, $d
proc_run('php',"include/notifier.php","activity",$item_id);
}
//call_hooks('post_local_end', $arr);
call_hooks('post_local_end', $arr);
unset($object['mid']); //remove mid for new object
//notice( t('File activity updated') . EOL);
@ -1025,9 +1073,11 @@ function file_activity($channel_id, $hash, $allow_cid, $allow_gid, $deny_cid, $d
$arr['deny_cid'] = $deny_cid;
$arr['deny_gid'] = $deny_gid;
$arr['item_restrict'] = ITEM_HIDDEN;
$arr['item_private'] = 0;
$arr['verb'] = $verb;
$arr['body'] = $url;
$arr['item_private'] = $private;
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;
$arr['object'] = json_encode($object);
$arr['body'] = '';
$post = item_store($arr);
$item_id = $post['item_id'];
@ -1036,9 +1086,9 @@ function file_activity($channel_id, $hash, $allow_cid, $allow_gid, $deny_cid, $d
proc_run('php',"include/notifier.php","activity",$item_id);
}
//call_hooks('post_local_end', $arr);
call_hooks('post_local_end', $arr);
//(($action === 'post') ? notice( t('File activity posted') . EOL) : notice( t('File activity dropped') . EOL));
//(($verb === 'post') ? notice( t('File activity posted') . EOL) : notice( t('File activity dropped') . EOL));
return;

View File

@ -176,7 +176,7 @@ function zot_zot($url,$data) {
*/
function zot_finger($webbie,$channel,$autofallback = true) {
function zot_finger($webbie,$channel = null,$autofallback = true) {
if(strpos($webbie,'@') === false) {

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,9 @@
opacity: 1;
z-index: 2;
}
.slider-container .back-bar .pointer.last-active {
z-index: 3;
}
.slider-container .back-bar .pointer-label {
position: absolute;
top: -17px;

View File

@ -33,7 +33,9 @@
step : 1,
format: '%s',
theme : 'theme-green',
width : 300
width : 300,
minRange: 0,
maxRange: 'auto'
},
template : '<div class="slider-container">\
<div class="back-bar">\
@ -103,7 +105,8 @@
if(e.which !== 1){return;}
e.stopPropagation(); e.preventDefault();
var pointer = $(e.target);
pointer.addClass('focused');
this.pointers.removeClass('last-active');
pointer.addClass('focused last-active');
this[(pointer.hasClass('low')?'low':'high') + 'Label'].addClass('focused');
$(document).on('mousemove.slider', $.proxy(this.onDrag, this, pointer));
$(document).on('mouseup.slider', $.proxy(this.onDragEnd, this));
@ -280,6 +283,7 @@
options = typeof option === 'object' && option;
if (!data) {
$this.data('plugin_' + pluginName, (data = new jRange(this, options)));
$(window).resize(function() { data.setValue(data.getValue()); }); // Update slider position when window is resized to keep it in sync with scale
}
// if first argument is a string, call silimarly named function
// this gives flexibility to call functions of the plugin e.g.
@ -294,4 +298,4 @@
return result || this;
};
})(jQuery, window, document);
})(jQuery, window, document);

View File

@ -73,6 +73,9 @@
cursor: move;
opacity: 1;
z-index: 2;
&.last-active{
z-index: 3;
}
}
.pointer-label {
position: absolute;

View File

@ -124,9 +124,8 @@ if (typeof jQuery === 'undefined') {
this.views = [];
this.option = $.extend({}, Completer._getDefaults(), option);
if (!this.$el.is('input[type=text]') && !this.$el.is('textarea') && !element.isContentEditable && element.contentEditable != 'true') {
throw new Error('textcomplete must be called on a input[type=text], Textarea or a ContentEditable.');
throw new Error('textcomplete must be called on a Textarea or a ContentEditable.');
}
if (element === document.activeElement) {
@ -414,6 +413,22 @@ if (typeof jQuery === 'undefined') {
setPosition: function (position) {
this.$el.css(this._applyPlacement(position));
// Make the dropdown fixed if the input is also fixed
// This can't be done during init, as textcomplete may be used on multiple elements on the same page
// Because the same dropdown is reused behind the scenes, we need to recheck every time the dropdown is showed
var position = 'absolute';
// Check if input or one of its parents has positioning we need to care about
this.$inputEl.add(this.$inputEl.parents()).each(function() {
if($(this).css('position') === 'absolute') // The element has absolute positioning, so it's all OK
return false;
if($(this).css('position') === 'fixed') {
position = 'fixed';
return false;
}
});
this.$el.css({ position: position }); // Update positioning
return this;
},

View File

@ -21,7 +21,6 @@ function filestorage_post(&$a) {
$recurse = ((x($_POST, 'recurse')) ? intval($_POST['recurse']) : 0);
$resource = ((x($_POST, 'filehash')) ? notags($_POST['filehash']) : '');
$no_activity = ((x($_POST, 'no_activity')) ? intval($_POST['no_activity']) : 0);
if(! $resource) {
@ -40,10 +39,7 @@ function filestorage_post(&$a) {
$channel = $a->get_channel();
$cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource);
$filename = find_filename_by_hash($channel_id, $resource);
$url = $cloudPath . $filename;
file_activity($channel_id, $resource, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $url, 'post', $no_activity);
file_activity($channel_id, $resource, $cloudPath, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, 'post', $no_activity);
goaway($cloudPath);
}

View File

@ -11,24 +11,28 @@ function locs_post(&$a) {
if($_REQUEST['primary']) {
$hubloc_id = intval($_REQUEST['primary']);
if($hubloc_id) {
$r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1",
intval($hubloc_id),
dbesc($channel['channel_hash'])
);
if(! $r) {
notice( t('Location not found.') . EOL);
return;
}
$r = q("update hubloc set hubloc_flags = (hubloc_flags & ~%d) where (hubloc_flags & %d)>0 and hubloc_hash = '%s' ",
$r = q("update hubloc set hubloc_flags = (hubloc_flags - %d) where (hubloc_flags & %d)>0 and hubloc_hash = '%s' ",
intval(HUBLOC_FLAGS_PRIMARY),
intval(HUBLOC_FLAGS_PRIMARY),
dbesc($channel['channel_hash'])
);
$r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s'",
$r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d and hubloc_hash = '%s'",
intval(HUBLOC_FLAGS_PRIMARY),
intval($hubloc_id),
dbesc($channel['channel_hash'])
);
proc_run('php','include/notifier.php','location',$channel['channel_id']);
return;
}
@ -36,12 +40,14 @@ function locs_post(&$a) {
if($_REQUEST['drop']) {
$hubloc_id = intval($_REQUEST['drop']);
if($hubloc_id) {
$r = q("select hubloc_id, hubloc_flags from hubloc where hubloc_id = %d and hubloc_url != '%s' and hubloc_hash = '%s' limit 1",
intval($hubloc_id),
dbesc(z_root()),
dbesc($channel['channel_hash'])
);
if(! $r) {
notice( t('Location not found.') . EOL);
return;
@ -50,7 +56,7 @@ function locs_post(&$a) {
notice( t('Primary location cannot be removed.') . EOL);
return;
}
$r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s'",
$r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d and hubloc_hash = '%s'",
intval(HUBLOC_FLAGS_DELETED),
intval($hubloc_id),
dbesc($channel['channel_hash'])

View File

@ -1,6 +1,6 @@
<?php
require_once('include/text.php');
require_once('include/conversation.php');
require_once('include/text.php');
function sharedwithme_content(&$a) {
if(! local_user()) {
@ -12,38 +12,44 @@ function sharedwithme_content(&$a) {
$is_owner = (local_user() && (local_user() == $channel['channel_id']));
$postverb = ACTIVITY_FILE . '/post/';
$dropverb = ACTIVITY_FILE . '/drop/';
//maintenance - see if a file got dropped and remove it systemwide
$x = q("SELECT * FROM item WHERE verb LIKE '%s' AND uid = %d",
dbesc($dropverb . '%'),
$x = q("SELECT * FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d",
dbesc(ACTIVITY_UPDATE),
dbesc(ACTIVITY_OBJ_FILE),
intval(local_user())
);
if($x) {
foreach($x as $xx) {
$hash = substr($xx['verb'], 39);
$object = json_decode($xx['object'],true);
$hash = $object['hash'];
$update = strpos($hash, '#');
//If object has a mid it's an update - the inlcuded mid is the latest and should not be removed
$update = (($object['mid']) ? true : false);
if($update === false) {
q("DELETE FROM item WHERE verb = '%s' OR verb = '%s'",
dbesc($postverb . $hash),
dbesc($dropverb . $hash)
if($update) {
$mid = $object['mid'];
$y = q("DELETE FROM item WHERE (mid != '%s' AND obj_type = '%s' AND object LIKE '%s') AND (verb = '%s' OR verb = '%s')",
dbesc($mid),
dbesc(ACTIVITY_OBJ_FILE),
dbesc('%"hash":"' . $hash . '"%'),
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_UPDATE)
);
}
else {
$arr = explode('#', $hash);
q("DELETE FROM item WHERE mid != '%s' AND verb = '%s' OR verb = '%s'",
dbesc($arr[1]),
dbesc($postverb . $arr[0]),
dbesc($dropverb . $hash)
$z = q("DELETE FROM item WHERE (obj_type = '%s' AND object LIKE '%s') AND (verb = '%s' OR verb = '%s')",
dbesc(ACTIVITY_OBJ_FILE),
dbesc('%"hash":"' . $hash . '"%'),
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_UPDATE)
);
}
@ -68,8 +74,9 @@ function sharedwithme_content(&$a) {
//drop all files - localuser
if((argc() > 1) && (argv(1) === 'dropall')) {
q("DELETE FROM item WHERE verb LIKE '%s' AND uid = %d",
dbesc($postverb . '%'),
q("DELETE FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d",
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_OBJ_FILE),
intval(local_user())
);
@ -77,11 +84,13 @@ function sharedwithme_content(&$a) {
}
//list files
$r = q("SELECT * FROM item WHERE verb LIKE '%s' AND uid = %d",
dbesc($postverb . '%'),
intval(local_user())
$r = q("SELECT * FROM item WHERE verb = '%s' AND obj_type = '%s' AND uid = %d AND owner_xchan != '%s'",
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_OBJ_FILE),
intval(local_user()),
dbesc($channel['channel_hash'])
);
$o = profile_tabs($a, $is_owner, $channel['channel_address']);
$o .= '<div class="section-title-wrapper">';
@ -96,19 +105,15 @@ function sharedwithme_content(&$a) {
if($r) {
foreach($r as $rr) {
//don't display the files we shared with others
if($rr['owner_xchan'] != $channel['channel_hash']) {
unobscure($rr);
$url = rawurldecode($rr['body']);
$o .= '<a href="' . $url . '?f=&zid=' . $channel['xchan_addr'] . '">' . $url . '</a>&nbsp;<a href="/sharedwithme/' . $rr['id'] . '/drop" onclick="return confirmDelete();"><i class="icon-trash drop-icons"></i></a><br><br>';
}
$object = json_decode($rr['object'],true);
$url = rawurldecode(get_rel_link($object['link'],'alternate'));
$o .= '<a href="' . $url . '?f=&zid=' . $channel['xchan_addr'] . '">' . $url . '</a>&nbsp;<a href="/sharedwithme/' . $rr['id'] . '/drop" onclick="return confirmDelete();"><i class="icon-trash drop-icons"></i></a><br><br>';
}
}
$o .= '</div>';
return $o;
}

View File

@ -1 +1 @@
2015-01-20.922
2015-01-21.923

View File

@ -5,4 +5,8 @@
.prep-details {
float: left;
}
.directory-item {
margin: 10px;
}

View File

@ -3,15 +3,18 @@
*
* require jQuery, jquery.textcomplete
*/
function contact_search(term, callback, backend_url, type, extra_channels) {
function contact_search(term, callback, backend_url, type, extra_channels, spinelement) {
if(spinelement){
$(spinelement).spin('tiny');
}
// Check if there is a cached result that contains the same information we would get with a full server-side search
var bt = backend_url+type;
if(!(bt in contact_search.cache)) contact_search.cache[bt] = {};
var lterm = term.toLowerCase(); // Ignore case
for(t in contact_search.cache[bt]) {
if(lterm.indexOf(t) >= 0) { // A more broad search has been performed already, so use those results
$(spinelement).spin(false);
// Filter old results locally
var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because groups don't have one
matching.unshift({taggable:false, text: term, replace: term});
@ -44,6 +47,7 @@ function contact_search(term, callback, backend_url, type, extra_channels) {
var items = data.items.slice(0);
items.unshift({taggable:false, text: term, replace: term});
callback(items);
$(spinelement).spin(false);
},
}).fail(function () {callback([]); }); // Callback must be invoked even if something went wrong.
}
@ -98,7 +102,7 @@ function submit_form(e) {
contacts = {
match: /(^|\s)(@\!*)([^ \n]+)$/,
index: 3,
search: function(term, callback) { contact_search(term, callback, backend_url, 'c', extra_channels); },
search: function(term, callback) { contact_search(term, callback, backend_url, 'c', extra_channels, spinelement=false); },
replace: editor_replace,
template: contact_format,
}
@ -125,7 +129,7 @@ function submit_form(e) {
contacts = {
match: /(^@)([^\n]{2,})$/,
index: 2,
search: function(term, callback) { contact_search(term, callback, backend_url, 'x',[]); },
search: function(term, callback) { contact_search(term, callback, backend_url, 'x', [], spinelement='#nav-search-spinner'); },
replace: basic_replace,
template: contact_format,
}
@ -147,7 +151,7 @@ function submit_form(e) {
contacts = {
match: /(^)([^\n]+)$/,
index: 2,
search: function(term, callback) { contact_search(term, callback, backend_url, typ,[]); },
search: function(term, callback) { contact_search(term, callback, backend_url, typ,[], spinelement=false); },
replace: basic_replace,
template: contact_format,
}

View File

@ -876,8 +876,8 @@ footer {
nav .acpopup {
top: 49px !important;
right: 30px !important;
margin-left: -45px;
margin-left: -35px;
width: 290px;
}
.profile-clear {

View File

@ -2,10 +2,10 @@
<script>
function primehub(id) {
$.post('locs','primary='+id,function(data) { window.location.href=window.location.href; });
$.post(baseurl + '/locs','primary='+id,function(data) { window.location.href=window.location.href; });
}
function drophub(id) {
$.post('locs','drop='+id,function(data) { window.location.href=window.location.href; });
$.post(baseurl + '/locs','drop='+id,function(data) { window.location.href=window.location.href; });
}
</script>
@ -17,7 +17,7 @@ function drophub(id) {
{{$hub.hubloc_url}} ({{$hub.hubloc_addr}}){{if $hub.deleted}}</strike>{{/if}}</td>
<td>
{{if $hub.primary}}<i class="icon-check"></i>{{else}}<button class="btn btn-std"><i class="icon-check-empty" onclick="primehub({{$hub.hubloc_id}}); return false;" ></i></button>{{/if}}
{{if $hub.primary}}<i class="icon-check"></i>{{else}}<button class="btn btn-std" onclick="primehub({{$hub.hubloc_id}}); return false;" ><i class="icon-check-empty" ></i></button>{{/if}}
</td>
<td>{{if $hub.primary}}{{else}}{{if ! $hub.deleted}}<button class="btn btn-std" onclick="drophub({{$hub.hubloc_id}}); return false;"><i class="icon-remove"></i></button>{{/if}}{{/if}}</td>
</tr>