Browse Source

- Split the old vcard widget to two brand new widgets : vcard4 and avatar

- Move the location widget into the profile page
pull/16/head
Jaussoin Timothée 12 years ago
parent
commit
901d69f120
  1. 18
      app/assets/js/movim_utils.js
  2. 1
      app/views/conf.tpl
  3. 1
      app/views/explore.tpl
  4. 1
      app/views/help.tpl
  5. 1
      app/views/main.tpl
  6. 1
      app/views/media.tpl
  7. 1
      app/views/news.tpl
  8. 1
      app/views/node.tpl
  9. 9
      app/views/profile.tpl
  10. 1
      app/views/server.tpl
  11. 68
      app/widgets/Avatar/Avatar.php
  12. 26
      app/widgets/Avatar/avatar.css
  13. 93
      app/widgets/Avatar/avatar.js
  14. 49
      app/widgets/Avatar/avatar.tpl
  15. 9
      app/widgets/Location/Location.php
  16. 1
      app/widgets/Vcard/vcard.js
  17. 125
      app/widgets/Vcard4/Vcard4.php
  18. 118
      app/widgets/Vcard4/vcard4.tpl
  19. 30
      system/Utils.php
  20. 4
      themes/movim/css/forms.css

18
app/assets/js/movim_utils.js

@ -159,6 +159,24 @@ function movim_toggle_class(element, classname) {
movim_add_class(element, classname);
}
/**
* @brief Save the current button class
* @param string the selector of the element
*/
function movim_button_save(element) {
var elt = document.querySelector(element);
elt.dataset.oldclassname = elt.className;
}
/**
* @brief Reset the button
* @param string the selector of the element
*/
function movim_button_reset(element) {
var elt = document.querySelector(element);
elt.className = elt.dataset.oldclassname;
}
/**
* @brief Toggle the visibility of an element
* @param string the selector of the element

1
app/views/conf.tpl

@ -11,7 +11,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<?php $this->widget('Tabs');?>
<div id="center">

1
app/views/explore.tpl

@ -10,7 +10,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<div id="center">
<div class="protect black" title="<?php echo getFlagTitle("black"); ?>"></div>

1
app/views/help.tpl

@ -11,7 +11,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<?php $this->widget('Tabs');?>
<div id="center">

1
app/views/main.tpl

@ -11,7 +11,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<div id="center">

1
app/views/media.tpl

@ -12,7 +12,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<div id="center">

1
app/views/news.tpl

@ -11,7 +11,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<div id="center">

1
app/views/node.tpl

@ -11,7 +11,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<div id="center">

9
app/views/profile.tpl

@ -14,11 +14,14 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<?php $this->widget('Tabs');?>
<div id="center">
<h1><?php echo t('Edit my profile'); ?></h1>
<?php $this->widget('Vcard');?>
<?php $this->widget('Vcard4');?>
<?php $this->widget('Avatar');?>
<?php $this->widget('Location');?>
</div>
</div>

1
app/views/server.tpl

@ -14,7 +14,6 @@
<?php $this->widget('Profile');?>
<?php $this->widget('Bookmark');?>
<?php $this->widget('Notifs');?>
<?php $this->widget('Location');?>
</div>
<?php $this->widget('Tabs');?>

68
app/widgets/Avatar/Avatar.php

@ -0,0 +1,68 @@
<?php
/**
* @package Widgets
*
* @file Avatar.php
* This file is part of Movim.
*
* @brief A widget which display all the infos of a contact, vcard 4 version
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
* Copyright (C)2013 MOVIM project
*
* See COPYING for licensing information.
*/
class Avatar extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('myavatarvalid', 'onAvatarPublished');
$this->registerEvent('myavatarinvalid', 'onAvatarNotPublished');
$this->addcss('avatar.css');
$this->addjs('avatar.js');
$cd = new \modl\ContactDAO();
$me = $cd->get($this->user->getLogin());
$this->view->assign('me', $me);
$this->view->assign(
'submit',
$this->genCallAjax('ajaxAvatarSubmit', "movim_form_to_json('avatarform')")
);
}
function onAvatarPublished()
{
RPC::call('movim_button_reset', '#avatarvalidate');
Notification::appendNotification(t('Avatar Updated'), 'success');
RPC::commit();
}
function onAvatarNotPublished()
{
Notification::appendNotification(t('Avatar Not Updated'), 'error');
RPC::commit();
}
function ajaxAvatarSubmit($avatar)
{
$cd = new \modl\ContactDAO();
$c = $cd->get($this->user->getLogin());
if($c == null)
$c = new modl\Contact();
$c->phototype = $avatar->phototype->value;
$c->photobin = $avatar->photobin->value;
$c->createThumbnails();
$cd->set($c);
$r = new moxl\AvatarSet();
$r->setData($avatar->photobin->value)->request();
}
}

26
app/widgets/Avatar/avatar.css

@ -0,0 +1,26 @@
#avatar img {
margin: 0 auto;
}
#avatar .element #runningcam,
#avatar .element #shoot{
display: none;
}
#avatar .element.active #runningcam{
display: block;
}
#avatar .element.active #shoot{
display: inline-block;
}
#avatar .element.active #capture {
display: none;
}
.squares, #snap{
height:200px;
box-shadow: none !important;
border: 0px !important;
}

93
app/widgets/Avatar/avatar.js

@ -0,0 +1,93 @@
function vCardImageResize(img) {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = 210;
var width = canvas.width;
var height = canvas.height;
if (img.width == img.height) {
canvas.getContext("2d").drawImage(img, 0, 0, width, height);
} else {
minVal = Math.min(img.width, img.height);
if (img.width > img.height) {
canvas.getContext("2d").drawImage(img, (img.width - minVal) / 2, 0, minVal, minVal, 0, 0, width, height);
} else {
canvas.getContext("2d").drawImage(img, 0, (img.height - minVal) / 2, minVal, minVal, 0, 0, width, height);
}
}
canvas.style.width = 200;
canvas.style.height = 200;
var base64 = canvas.toDataURL('image/jpeg', 0.9);
var bin = base64.split(",");
document.querySelector('#vCardPhotoPreview').src = base64;
document.querySelector('input[name="phototype"]').value = 'image/jpeg';
document.querySelector('input[name="photobin"]').value = bin[1];
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
document.getElementById("picturesize").innerHTML = bytesToSize(encodeURI(base64).split(/%..|./).length - 1);
};
function vCardImageLoad(files) {
var f = files[0];
if (!f.type.match(/image.*/)) {
console.log("Not a picture !");
} else {
var reader = new FileReader();
reader.readAsDataURL(f);
reader.onload = function ( ev ) {
var img = new Image();
img.src = ev.target.result;
img.onload = function() {
vCardImageResize(this);
};
};
};
};
function showVideo(){
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia({video:true, audio:false}, successCallback, errorCallback);
movim_toggle_class('#camdiv', 'active');
}
function successCallback(stream) {
video = document.getElementById("runningcam");
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream; // stream available to console
document.getElementById("shoot").addEventListener('click', snapshot, false);
}
function errorCallback(error){
console.log("navigator.getUserMedia error: ", error);
}
function snapshot() {
if (localMediaStream) {
canvas = document.querySelector("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx = canvas.getContext('2d');
video = document.getElementById("runningcam");
ctx.drawImage(video,0,0, canvas.width, canvas.height);
// "image/webp" works in Chrome 18. In other browsers, this will fall back to image/png.
var img = new Image();
img.src = canvas.toDataURL('image/png');
img.onload = function() {
vCardImageResize(this);
}
}
}

49
app/widgets/Avatar/avatar.tpl

@ -0,0 +1,49 @@
<div class="tabelem padded" title="{$c->t('Avatar')}" id="avatar" >
<form name="avatarform" id="avatarform">
<fieldset>
<legend>{$c->t('Avatar')}</legend>
<div class="element">
<label for="avatar">{$c->t('Avatar')}</label>
<img id="vCardPhotoPreview" src="data:'.$me->phototype.';base64,{$me->photobin}">
<br /><span id="picturesize" class="clean"></span><br /><br />
<input type="file" onchange="vCardImageLoad(this.files);">
<input type="hidden" name="phototype" value="{$me->phototype}"/>
<input type="hidden" name="photobin" value="{$me->photobin}"/>
</div>
<div class="element" id="camdiv">
<label for="url">{$c->t('Webcam')}</label>
<video id="runningcam" class="squares" autoplay></video>
<canvas style="display:none;"></canvas>
<a
id="shoot"
class="button icon preview color green"
onclick="return false;">
{$c->t("Cheese !")}
</a>
<a
id="capture"
class="button icon image color purple"
onclick="
showVideo();
return false;">
{$c->t("Take a webcam snapshot")}
</a>
</div>
</fieldset>
<a
onclick="
{$submit}
movim_button_save('#avatarvalidate');
this.value = '{$c->t('Submitting')}';
this.className='button color orange icon loading inactive';"
class="button icon color green yes"
id="avatarvalidate"
style="float: right;"
>{$c->t('Submit')}</a>
</form>
</div>

9
app/widgets/Location/Location.php

@ -91,14 +91,13 @@ class Location extends WidgetBase
$html = '';
$html .= '
<h2>'.t('Location').'</h2>
<div id="location">
<div id="mapdata" style="margin-bottom: 10px;">'.$data.'</div>
<div id="mapdiv" style="width: auto; height: 250px; display: none;"></div>
<div class="clear"></div>
<a
class="button color green icon geo"
style="margin-top: 1em; display: block;"
style="margin-top: 1em;"
onclick="getMyPosition(); this.style.display = \'none\';">'.
t('Update my position').'
</a>
@ -118,6 +117,10 @@ class Location extends WidgetBase
function build()
{
echo $this->prepareProfileData();
?>
<div class="tabelem padded" title="<?php echo t('Location'); ?>" id="location" >
<?php echo $this->prepareProfileData(); ?>
</div>
<?php
}
}

1
app/widgets/Vcard/vcard.js

@ -105,6 +105,5 @@ function snapshot() {
img.onload = function() {
vCardImageResize(this);
}
//document.querySelector("#snap").src = canvas.toDataURL('image/webp');
}
}

125
app/widgets/Vcard4/Vcard4.php

@ -0,0 +1,125 @@
<?php
/**
* @package Widgets
*
* @file Vcard4.php
* This file is part of MOVIM.
*
* @brief A widget which display all the infos of a contact, vcard 4 version
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
* Copyright (C)2013 MOVIM project
*
* See COPYING for licensing information.
*/
class Vcard4 extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('myvcard4valid', 'onMyVcard4Received');
$this->registerEvent('myvcard4invalid', 'onMyVcard4NotReceived');
$cd = new \modl\ContactDAO();
$me = $cd->get($this->user->getLogin());
$this->view->assign('me', $me);
$this->view->assign('desc', trim($me->description));
$this->view->assign('gender', getGender());
$this->view->assign('marital', getMarital());
$this->view->assign(
'submit',
$this->genCallAjax('ajaxVcardSubmit', "movim_form_to_json('vcard4')")
);
// The datepicker arrays
$days = $months = $years = array();
for($i=1; $i<= 31; $i++) {
if($i < 10){
$j = '0'.$i;
} else {
$j = (string)$i;
}
$days[$i] = $j;
}
for($i=1; $i<= 12; $i++) {
if($i < 10){
$j = '0'.$i;
} else {
$j = (string)$i;
}
$m = getMonths();
$months[$j] = $m[$i];
}
for($i=date('o'); $i>= 1920; $i--) { array_push($years, $i); }
$this->view->assign('days', $days);
$this->view->assign('months', $months);
$this->view->assign('years', $years);
}
function onMyVcard4Received()
{
RPC::call('movim_button_reset', '#vcard4validate');
Notification::appendNotification(t('Profile Updated'), 'success');
RPC::commit();
}
function onMyVcard4NotReceived()
{
Notification::appendNotification(t('Profile Not Updated'), 'error');
RPC::commit();
}
function ajaxVcardSubmit($vcard)
{
# Format it ISO 8601:
if($vcard->year->value != -1
&& $vcard->month->value != -1
&& $vcard->day->value != -1)
$vcard->date->value =
$vcard->year->value.'-'.
$vcard->month->value.'-'.
$vcard->day->value;
unset($vcard->year->value);
unset($vcard->month->value);
unset($vcard->day->value);
$cd = new \modl\ContactDAO();
$c = $cd->get($this->user->getLogin());
if($c == null)
$c = new modl\Contact();
$c->jid = $this->user->getLogin();
if(isset($vcard->date->value)) {
$date = strtotime($vcard->date->value);
$c->date = date('Y-m-d', $date);
}
$c->name = $vcard->name->value;
$c->fn = $vcard->fn->value;
$c->url = $vcard->url->value;
$c->gender = $vcard->gender->value;
$c->marital = $vcard->marital->value;
$c->email = $vcard->email->value;
$c->description = trim($vcard->desc->value);
$cd = new modl\ContactDAO();
$cd->set($c);
$r = new moxl\Vcard4Set();
$r->setData($vcard)->request();
$r = new moxl\VcardSet();
$r->setData($vcard)->request();
}
}

118
app/widgets/Vcard4/vcard4.tpl

@ -0,0 +1,118 @@
<div class="tabelem padded" title="{$c->t('Data')}" id="vcard4" >
<form name="vcard4" id="vcard4form">
<fieldset>
<legend>{$c->t('General Informations')}</legend>
<div class="element">
<label for="fn">{$c->t('Name')}</label>
<input type="text" name="fn" class="content" value="{$me->fn}">
</div>
<div class="element">
<label for="fn">{$c->t('Nickname')}</label>
<input type="text" name="name" class="content" value="{$me->name}">
</div>
<div class="element">
<label for="fn">{$c->t('Email')}</label>
<input type="email" name="email" class="content" value="{$me->email}">
</div>
<!-- The date picker -->
<div class="element ">
<label for="day">{$c->t('Date of Birth')}</label>
<div class="select" style="width: 33%; float: left;">
<select name="day" class="datepicker">
<option value="-1">{$c->t('Day')}</option>
{loop="$days"}
<option value="{$value}"
{if="$key == substr($me->date, 8)"}
selected
{/if}
>{$value}</option>
{/loop}
</select>
</div>
<div class="select" style="width: 34%; float: left;">
<select name="month" class="datepicker">
<option value="-1">{$c->t('Month')}</option>
{loop="$months"}
<option value="{$key}"
{if="$key == substr($me->date,5,2)"}
selected
{/if}
>{$value}</option>
{/loop}
</select>
</div>
<div class="select" style="width: 33%; float: left;">
<select name="year" class="datepicker">
<option value="-1">{$c->t('Year')}</option>
{loop="$years"}
<option value="{$value}"
{if="$value == substr($me->date,0,4)"}
selected
{/if}
>{$value}</option>
{/loop}
</select>
</div>
</div>
<div class="element">
<label for="gender">{$c->t('Gender')}</label>
<div class="select">
<select name="gender">
{loop="$gender"}
<option
{if="$key == $me->gender"}
selected
{/if}
value="{$key}">{$value}</option>
{/loop}
</select>
</div>
</div>
<div class="element">
<label for="marital">{$c->t('Marital Status')}</label>
<div class="select">
<select name="marital">
{loop="$marital"}
<option
{if="$key == $me->marital"}
selected
{/if}
value="{$key}">{$value}</option>
{/loop}
</select>
</div>
</div>
<div class="element large">
<label for="url">{$c->t('Website')}</label>
<input type="url" name ="url" class="content" value="{$me->url}">
</div>
<div class="element large">
<label for="desc">{$c->t('About Me')}</label>
<textarea name="desc" id="desctext" class="content" onkeyup="movim_textarea_autoheight(this);">{$desc}</textarea>
</div>
</fieldset>
<a
onclick="
{$submit}
movim_button_save('#vcard4validate');
this.value = '{$c->t('Submitting')}';
this.className='button color orange icon loading merged right inactive';"
class="button icon merged right color green yes"
style="float: right;"
id="vcard4validate"
>{$c->t('Submit')}</a>
<a
onclick="document.querySelector('#vcard4form').reset();"
class="button icon no merged left color orange"
style="float: right;">{$c->t('Reset')}</a>
</form>
</div>

30
system/Utils.php

@ -150,14 +150,11 @@ function cleanHTMLTags($string) {
}
/**
* Return a human-readable date
*
* @param timestamp $string
* Return a human-readable week
* @return string
*/
function prepareDate($time, $hours = true) {
$dotw = array(
function getDays() {
return array(
1 => t('Monday'),
2 => t('Tuesday'),
3 => t('Wednesday'),
@ -165,8 +162,13 @@ function prepareDate($time, $hours = true) {
5 => t('Friday'),
6 => t('Saturday'),
7 => t('Friday'));
$moty = array(
}
/**
* Return a human-readable year
* @return string
*/
function getMonths() {
return array(
1 => t('January'),
2 => t('February'),
3 => t('March'),
@ -179,6 +181,18 @@ function prepareDate($time, $hours = true) {
10 => t('October'),
11 => t('November'),
12 => t('December'));
}
/**
* Return a human-readable date
*
* @param timestamp $string
* @return string
*/
function prepareDate($time, $hours = true) {
$dotw = getDays();
$moty = getMonths();
$today = strtotime(date('M j, Y'));
$reldays = ($time - $today)/86400;

4
themes/movim/css/forms.css

@ -339,6 +339,10 @@ legend {
border-radius: 0px 0.1em 0.1em 0px;
}
.button.inactive {
pointer-events:none;
}
.icon.yes:before { background-image: url(../img/icons/button/checkmark.svg); }
.icon.no:before { background-image: url(../img/icons/button/close.svg); }
.icon.chat:before { background-image: url(../img/icons/button/bubbles.svg);}

Loading…
Cancel
Save