$ git clone https://socialnetwork.ion.nu/socialnetwork-web.git
commit fa5239f69c4fa8b09ebde20b42366d9f5ab21dbb
Author: Alicia <...>
Date: Sat Jul 22 12:50:46 2017 +0200
Implemented privacy getting/setting.
diff --git a/Makefile b/Makefile
index 6677b19..9d07c5d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ SOCIALNETWORKREVISION=f5e92db17a617d4777df4b7a1107d67114d3b6f9
REVISION=$(shell git log | sed -n -e 's/^commit //p;q')
JSLIBS=$(shell PKG_CONFIG_PATH=toolchain/usr/lib/pkgconfig pkg-config --libs gnutls nettle hogweed) -lgmp
JSCFLAGS=$(shell PKG_CONFIG_PATH=toolchain/usr/lib/pkgconfig pkg-config --cflags gnutls)
-JSSYMBOLS='_social_init','_peer_handlesocket','_peer_new_unique','_websockproxy_read','_websockproxy_setwrite','_getcirclecount','_newcircle','_circle_getcount','_circle_getname','_circle_setname','_social_addfriend','_circle_getid','_social_finduser','_self_getid','_user_getupdatecount','_user_getupdatetype','_user_getupdatetimestamp'
+JSSYMBOLS='_social_init','_peer_handlesocket','_peer_new_unique','_websockproxy_read','_websockproxy_setwrite','_getcirclecount','_circle_getcount','_circle_getname','_circle_getprivacyptr','_social_addfriend','_circle_getid','_social_finduser','_self_getid','_user_getupdatecount','_user_getupdatetype','_user_getupdatetimestamp','_setcircle','_privacy_getflags','_privacy_getcirclecount','_privacy_getcircle'
all: webpeer libsocial.js
diff --git a/jsglue.c b/jsglue.c
index bf0b858..e140e43 100644
--- a/jsglue.c
+++ b/jsglue.c
@@ -50,27 +50,6 @@ unsigned int getcirclecount(void)
{
return social_self->circlecount;
}
-
-// Find an empty circle and reset it, empty and nameless I guess, then return its index
-unsigned int newcircle(void)
-{
- unsigned int i;
- for(i=0; i<social_self->circlecount; ++i)
- {
- if(!social_self->circles[i].count && !social_self->circles[i].name){break;}
- }
- if(i==social_self->circlecount)
- {
- ++social_self->circlecount;
- social_self->circles=realloc(social_self->circles, social_self->circlecount*sizeof(struct friendslist));
- }else{
- free(social_self->circles[i].privacy.circles);
- }
- memset(&social_self->circles[i], 0, sizeof(struct friendslist));
- return i;
-}
-// TODO: how to configure privacy structs?
-
unsigned int circle_getcount(unsigned int i)
{
if(i>=social_self->circlecount){return 0;}
@@ -90,12 +69,16 @@ const char* circle_getname(unsigned int i)
if(i>=social_self->circlecount){return 0;}
return social_self->circles[i].name;
}
-void circle_setname(unsigned int i, const char* name)
+void setcircle(uint32_t circle, const char* name, uint8_t flags, void* circles, uint32_t circlecount)
{
- if(i>=social_self->circlecount){return;}
- free(social_self->circles[i].name);
- social_self->circles[i].name=strdup(name);
+ struct privacy priv={
+ .flags=flags,
+ .circles=circles,
+ .circlecount=circlecount
+ };
+ social_setcircle(circle, name, &priv);
}
+struct privacy* circle_getprivacyptr(uint32_t circle){return &social_self->circles[circle].privacy;}
unsigned int user_getupdatecount(struct user* user){return user->updatecount;}
const char* user_getupdatetype(struct user* user, unsigned int index)
{
@@ -120,3 +103,6 @@ const char* self_getid(void)
sprintf(id, PEERFMT, PEERARG(social_self->id));
return id;
}
+uint8_t privacy_getflags(struct privacy* priv){return priv->flags;}
+uint32_t privacy_getcirclecount(struct privacy* priv){return priv->circlecount;}
+uint32_t privacy_getcircle(struct privacy* priv, uint32_t i){return priv->circles[i];}
diff --git a/libsocialjs.js b/libsocialjs.js
index 2f65c8c..097d444 100644
--- a/libsocialjs.js
+++ b/libsocialjs.js
@@ -26,17 +26,20 @@ function websockwrite(addr, addrlen, buf, size)
var websockproxy_read;
var peer_new_unique;
var getcirclecount;
-var newcircle;
var circle_getcount;
var circle_getname;
-var circle_setname;
var circle_getid;
+var setcircle;
+var circle_getprivacyptr;
var social_addfriend;
var social_finduser;
var user_getupdatecount;
var user_getupdatetype;
var user_getupdatetimestamp;
var self_getid;
+var privacy_getflags;
+var privacy_getcirclecount;
+var privacy_getcircle;
var websockproxy_to=false;
var firstpacket=true;
@@ -73,17 +76,20 @@ function init(privkey)
peer_new_unique=Module.cwrap('peer_new_unique', 'array', ['number', 'array', 'number']);
// Low level access functions
getcirclecount=Module.cwrap('getcirclecount', 'number', []);
- newcircle=Module.cwrap('newcircle', 'number', []);
circle_getcount=Module.cwrap('circle_getcount', 'number', ['number']);
circle_getname=Module.cwrap('circle_getname', 'string', ['number']);
- circle_setname=Module.cwrap('circle_setname', null, ['number', 'string']);
circle_getid=Module.cwrap('circle_getid', 'string', ['number','number']);
+ setcircle=Module.cwrap('setcircle', null, ['number','string','number','array','number']);
+ circle_getprivacyptr=Module.cwrap('circle_getprivacyptr', 'number', ['number']);
social_addfriend=Module.cwrap('social_addfriend', null, ['array', 'number']);
social_finduser=Module.cwrap('social_finduser', 'number', ['array']);
user_getupdatecount=Module.cwrap('user_getupdatecount', 'number', ['number']);
user_getupdatetype=Module.cwrap('user_getupdatetype', 'string', ['number','number']);
user_getupdatetimestamp=Module.cwrap('user_getupdatetimestamp', 'number', ['number','number']);
self_getid=Module.cwrap('self_getid', 'string', []);
+ privacy_getflags=Module.cwrap('privacy_getflags', 'number', ['number']);
+ privacy_getcirclecount=Module.cwrap('privacy_getcirclecount', 'number', ['number']);
+ privacy_getcircle=Module.cwrap('privacy_getcircle', 'number', ['number', 'number']);
_websockproxy_setwrite(Runtime.addFunction(websockwrite));
FS.writeFile('privkey.pem', privkey, {});
@@ -116,6 +122,34 @@ function circle_getfriends(index)
}
return friends;
}
+function newcircle()
+{
+ var len=getcirclecount();
+ for(var i=0; i<len; ++i)
+ {
+ var name=circle_getname(i);
+ var count=circle_getcount(i);
+ if((!name || name=='') && count==0){break;}
+ }
+ return i;
+}
+function circle_getprivacy(index)
+{
+ var ptr=circle_getprivacyptr(index);
+ return getprivacy(ptr);
+}
+function circle_set(index, name, priv)
+{
+ var circles=[];
+ for(circle of priv.circles) // Can only pass Uint8 arrays, so construct our Uint32 values from Uint8 pieces
+ {
+ circles.push(circle.index&0xff);
+ circles.push((circle.index&0xff00)/0x100);
+ circles.push((circle.index&0xff0000)/0x10000);
+ circles.push((circle.index&0xff000000)/0x1000000);
+ }
+ setcircle(configcircle_index, name, priv.flags, new Uint8Array(circles), priv.circles.length);
+}
function hextobin(hex)
{
var bin=new Array();
@@ -144,3 +178,24 @@ function user_getupdate(user, index)
// TODO: Get type-specific data
return update;
}
+function privacy(flags, circles)
+{
+ this.flags=flags;
+ this.circles=circles;
+}
+function getprivacy(ptr)
+{
+ var flags=privacy_getflags(ptr);
+ var count=privacy_getcirclecount(ptr);
+ var circles=[];
+ for(var i=0; i<count; ++i)
+ {
+ var index=privacy_getcircle(ptr, i);
+ var circle={
+ 'name':circle_getname(index),
+ 'index':index
+ };
+ circles.push(circle);
+ }
+ return new privacy(flags, circles);
+}
diff --git a/websocial.html b/websocial.html
index 26a9885..b205bca 100644
--- a/websocial.html
+++ b/websocial.html
@@ -46,11 +46,11 @@
<div class="modal" id="circle_window" style="display:none;">
Name:<input type="text" id="circle_name" /><br />
Privacy:<select id="circle_privacy">
- <option>Select circles only</option>
- <option>Friends</option>
- <option>Everyone</option>
+ <option value="0">Select circles only</option>
+ <option value="2">Friends</option>
+ <option value="1">Everyone</option>
</select><br />
- <div id="circle_circles"></div><br />
+ <div id="circle_privacy_circles"></div><br />
<button onclick="circle_save();">OK</button> <button onclick="chdisplay('circle_window',false);">Cancel</button>
</div>
<!-- Main interface -->
diff --git a/websocial.js b/websocial.js
index 78e6890..e6e4c0c 100644
--- a/websocial.js
+++ b/websocial.js
@@ -103,8 +103,7 @@ function page_friends()
{
if(this.value=='new')
{
- configcircle_option=this.selectedOptions[0];
- circle_openconfig(newcircle());
+ circle_openconfig(newcircle(), this.selectedOptions[0]);
}
}
box.appendChild(circle);
@@ -114,7 +113,6 @@ function page_friends()
{
if(circle.value=='new') // Need to create the circle first
{
- configcircle_option=circle.selectedOptions[0]; // option;
circle.onchange();
return;
}
@@ -127,7 +125,12 @@ function page_friends()
// TODO: Make this prettier, links to individual profile pages and get the name property
for(item of circles)
{
- display.appendChild(document.createTextNode('Circle '+item.name+':'));
+ display.appendChild(document.createTextNode('Circle '+item.name+': '));
+ var button=document.createElement('button');
+ button.appendChild(document.createTextNode('Options'));
+ button.dataset.index=item.index;
+ button.onclick=function(){circle_openconfig(this.dataset.index, false);};
+ display.appendChild(button);
display.appendChild(document.createElement('br'));
var count=circle_getcount(item.index);
for(var i=0; i<count; ++i)
@@ -161,15 +164,70 @@ function page_user(id)
// TODO: Option to load more updates
}
+function privacy_openconfig(prefix, priv)
+{
+ var circlebox=document.getElementById(prefix+'_privacy_circles');
+ dom_clear(circlebox);
+ var listed=[];
+ function listcircle(item, check)
+ {
+ if(listed.indexOf(item.index)>-1){return;}
+ listed.push(item.index);
+ var label=document.createElement('label');
+ if(item.title){label.title=item.title;}
+ var checkbox=document.createElement('input');
+ if(check){checkbox.checked=true;}
+ checkbox.type='checkbox';
+ checkbox.name=prefix+'_privacy_circles';
+ checkbox.value=item.index;
+ label.appendChild(checkbox);
+ label.appendChild(document.createTextNode(item.name+' '));
+ circlebox.appendChild(label);
+ }
+ if(priv) // Populate with circles from existing privacy
+ {
+ document.getElementById(prefix+'_privacy').value=priv.flags; // And the flags
+ for(item of priv.circles)
+ {
+ listcircle(item, true);
+ }
+ }
+ // Populate with circles from libsocial
+ var circles=getcircles();
+ for(item of circles)
+ {
+ listcircle(item, false);
+ }
+}
+
+function privacy_save(prefix)
+{
+ var circles=[];
+ var flags=document.getElementById(prefix+'_privacy').value;
+ var items=document.getElementsByName(prefix+'_privacy_circles');
+ for(item of items)
+ {
+ if(item.checked){circles.push({'index':item.value});}
+ }
+ return new privacy(flags, circles);
+}
+
var configcircle_index;
var configcircle_option=false;
-function circle_openconfig(index)
+function circle_openconfig(index, option)
{
- // TODO: Move circle-list population to its own function? likely needed for other privacy settings
- var circles=document.getElementById('circle_circles');
- dom_clear(circles);
- // TODO: Populate with circles from libsocial
- // TODO: Store index and checkbox elements for circle_save()
+ configcircle_option=option;
+ if(option && option.value=='new')
+ {
+ var priv={'flags':0,'circles':[{
+ 'index':index,
+ 'name':'This circle',
+ 'title':'Let friends in this circle know about your other friends in the circle'
+ }]};
+ }else{
+ var priv=circle_getprivacy(index);
+ }
+ privacy_openconfig('circle', priv);
var name=document.getElementById('circle_name');
name.value=circle_getname(index);
configcircle_index=index;
@@ -179,7 +237,8 @@ function circle_openconfig(index)
function circle_save()
{
var name=document.getElementById('circle_name');
- circle_setname(configcircle_index, name.value);
+ var priv=privacy_save('circle');
+ circle_set(configcircle_index, name.value, priv);
if(configcircle_option)
{
var select=configcircle_option.parentNode;