pictures table

This commit is contained in:
2019-02-03 01:26:56 +01:00
parent 0239bb0551
commit 3c4bafec64
14 changed files with 1751 additions and 1550 deletions

View File

@@ -0,0 +1,14 @@
CREATE TABLE `pictures` (
`id_picture` int(10) UNSIGNED auto_increment,
`id_project` int(10) UNSIGNED,
`filename` VARCHAR(100) NOT NULL,
`taken_on` DATETIME,
`timestamp` DATETIME,
`rotate` SMALLINT,
`led` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id_picture`),
UNIQUE KEY `uni_file_name` (`filename`)
);
ALTER TABLE pictures ADD INDEX(`id_project`);
ALTER TABLE pictures ADD FOREIGN KEY (`id_project`) REFERENCES projects(`id_project`);

147
inc/picture.php Normal file
View File

@@ -0,0 +1,147 @@
<?php
class Picture extends PhpObject {
//DB Tables
const PIC_TABLE = 'pictures';
//Picture folders
const PIC_FOLDER = 'files/';
const THUMB_FOLDER = self::PIC_FOLDER.'thumbs/';
/**
* Database Handle
* @var Db
*/
private $oDb;
/**
* Picture Project
* @var Project
*/
private $oProject;
private $asPics;
public function __construct(Db &$oDb, &$oProject) {
parent::__construct(__CLASS__, Settings::DEBUG);
$this->oDb = &$oDb;
$this->oProject = &$oProject;
}
public function getPicsInfo() {
if(empty($this->asPics)) {
if($this->oProject->getProjectId()) {
$asPics = $this->oDb->selectRows(array(
'select' => array(Db::getId(self::PIC_TABLE), 'filename', 'taken_on', 'timestamp AS added_on', 'rotate'),
'from' => self::PIC_TABLE,
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId())
));
foreach($asPics as &$asPic) {
$asPic['pic_path'] = self::getPicPath($asPic['filename']);
$asPic['thumb_path'] = self::getPicThumbnail($asPic['filename']);
}
$this->asPics = $asPics;
}
}
return $this->asPics;
}
public function isProjectModeValid() {
return ($this->oProject->getMode() == Project::MODE_BLOG);
}
public function addPic($sPicName, $sMethod='upload') {
$sError = '';
if(!$this->isProjectModeValid() && $sMethod!='sync') $sError = 'Le projet (id='.$this->oProject->getProjectId().') n\'est pas en mode "blog"';
elseif($this->oDb->pingValue(self::PIC_TABLE, array('filename'=>$sPicName))) $sError = 'l\'image existe déjà';
else {
//Add picture to DB
$asPicInfo = self::getPicInfo($sPicName);
$iPicId = $this->oDb->insertRow(self::PIC_TABLE, array(
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
'filename' => $sPicName,
'taken_on' => date(Db::TIMESTAMP_FORMAT, $asPicInfo['taken_ts']),
'timestamp' => date(Db::TIMESTAMP_FORMAT, $asPicInfo['file_ts']),
'rotate' => $asPicInfo['rotate']
));
if(!$iPicId) $sError = 'l\'image n\'a pas pu être entrée en base';
else {
//Create thumbnail
self::getPicThumbnail($sPicName);
}
}
if($sError!='') {
$sError = 'Erreur lors de l\'ajout de "'.$sPicName.'" : '.$sError;
$this->addError($sError);
}
return $sError;
}
/**
* One-shot function to initialize DB with existing images
*/
public function syncFileFolder() {
$asPicPaths = glob(self::getPicPath('*.{jpg,JPG,jpeg,JPEG,png,PNG}'), GLOB_BRACE);
foreach($asPicPaths as $sPicPath)
{
$sPicName = pathinfo($sPicPath, PATHINFO_BASENAME);
$this->addPic($sPicName, 'sync');
}
$this->setExtractMode(PhpObject::MODE_HTML);
return $this->getCleanMessageStack();
}
private static function getPicInfo($sPicName)
{
$sPicPath = self::getPicPath($sPicName);
$iPicTimeStamp = $iPicTakenTimeStamp = $iPicFileTimeStamp = 0;
$asExif = @exif_read_data($sPicPath, 0, true);
if(!$asExif) $asExif['FILE']['FileDateTime'] = filemtime($sPicPath);
//Timestamps
if(array_key_exists('EXIF', $asExif) && array_key_exists('DateTimeOriginal', $asExif['EXIF'])) $iPicTakenTimeStamp = strtotime($asExif['EXIF']['DateTimeOriginal']);
if(array_key_exists('FILE', $asExif) && array_key_exists('FileDateTime', $asExif['FILE'])) $iPicFileTimeStamp = $asExif['FILE']['FileDateTime'];
//Merge timestamps
$iPicTimeStamp = ($iPicTakenTimeStamp > 0)?$iPicTakenTimeStamp:$iPicFileTimeStamp;
//Orientation
if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) {
switch($asExif['IFD0']['Orientation'])
{
case 1: $sRotate = '0'; break; //None
case 3: $sRotate = '180'; break; //Flip over
case 6: $sRotate = '90'; break; //Clockwise
case 8: $sRotate = '-90'; break; //Trigo
default: $sRotate = '0';
}
}
else $sRotate = '0';
return array(
'timestamp' => $iPicTimeStamp,
'taken_ts' => $iPicTakenTimeStamp,
'file_ts' => $iPicFileTimeStamp,
'rotate' => $sRotate
);
}
private static function getPicThumbnail($sPicName)
{
$sPicPath = self::getPicPath($sPicName);
$sThumbPath = self::getPicPath($sPicName, 'thumbnail');
if(!file_exists($sThumbPath)) $asThumbInfo = ToolBox::createThumbnail($sPicPath, 400, 0, $sThumbPath/*, false, array('jpg', 'jpeg', 'gif', 'png'), true*/);
else $asThumbInfo = array('error'=>'', 'out'=>$sThumbPath);
return ($asThumbInfo['error']=='')?$asThumbInfo['out']:$sPicPath;
}
private static function getPicPath($sPicName, $sFileType='picture') {
return ($sFileType=='thumbnail'?self::THUMB_FOLDER:self::PIC_FOLDER).$sPicName;
}
}

View File

@@ -29,7 +29,7 @@ class Project extends PhpObject {
public function __construct(Db &$oDb) { public function __construct(Db &$oDb) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__, Settings::DEBUG);
$this->oDb = $oDb; $this->oDb = &$oDb;
} }
public function setProjectId($iProjectId=0) { public function setProjectId($iProjectId=0) {

View File

@@ -13,10 +13,6 @@ class Spot extends Main
const SPOT_TABLE = 'spots'; const SPOT_TABLE = 'spots';
const POST_TABLE = 'posts'; const POST_TABLE = 'posts';
//Picture folders
const PIC_FOLDER = 'files/';
const THUMB_FOLDER = self::PIC_FOLDER.'thumbs/';
const FORMAT_TIME = 'd/m/Y à H:i'; const FORMAT_TIME = 'd/m/Y à H:i';
const FEED_CHUNK_SIZE = 15; const FEED_CHUNK_SIZE = 15;
@@ -27,15 +23,23 @@ class Spot extends Main
*/ */
private $oProject; private $oProject;
/**
* Picture Class
* @var Picture
*/
private $oPicture;
public function __construct($oClassManagement, $sProcessPage) public function __construct($oClassManagement, $sProcessPage)
{ {
$asClasses = array( $asClasses = array(
array('name'=>'project', 'project'=>true), array('name'=>'project', 'project'=>true),
array('name'=>'picture', 'project'=>true),
array('name'=>'cacher', 'project'=>true) array('name'=>'cacher', 'project'=>true)
); );
parent::__construct($oClassManagement, $sProcessPage, $asClasses); parent::__construct($oClassManagement, $sProcessPage, $asClasses);
$this->oProject = new Project($this->oDb); $this->oProject = new Project($this->oDb);
$this->oPicture = new Picture($this->oDb, $this->oProject);
} }
protected function install() protected function install()
@@ -54,7 +58,8 @@ class Spot extends Main
self::FEED_TABLE => array('ref_feed_id', Db::getId(self::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'), self::FEED_TABLE => array('ref_feed_id', Db::getId(self::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
self::SPOT_TABLE => array('ref_spot_id', 'name', 'model'), self::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'geofile', 'timezone'), Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'geofile', 'timezone'),
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), 'name', 'content', 'timestamp') self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), 'name', 'content', 'timestamp'),
Picture::PIC_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'taken_on', 'timestamp', 'rotate')
), ),
'types' => array 'types' => array
( (
@@ -77,7 +82,10 @@ class Spot extends Main
'active_to' => "DATETIME", 'active_to' => "DATETIME",
'geofile' => "VARCHAR(50)", 'geofile' => "VARCHAR(50)",
'timezone' => "VARCHAR(100)", 'timezone' => "VARCHAR(100)",
'last_update' => "DATETIME" 'last_update' => "DATETIME",
'filename' => "VARCHAR(100) NOT NULL",
'taken_on' => "DATETIME",
'rotate' => "SMALLINT"
), ),
'constraints' => array 'constraints' => array
( (
@@ -88,6 +96,7 @@ class Spot extends Main
self::FEED_TABLE => "INDEX(`ref_feed_id`)", self::FEED_TABLE => "INDEX(`ref_feed_id`)",
self::SPOT_TABLE => "INDEX(`ref_spot_id`)", self::SPOT_TABLE => "INDEX(`ref_spot_id`)",
Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)", Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)",
Picture::PIC_TABLE => "UNIQUE KEY `uni_file_name` (`filename`)"
), ),
'cascading_delete' => array 'cascading_delete' => array
( (
@@ -180,7 +189,7 @@ class Spot extends Main
} }
} }
public function getMessages() public function getMarkers()
{ {
/* Adding another point to test /* Adding another point to test
$test = $this->oDb->selectRow(self::MSG_TABLE, 1); $test = $this->oDb->selectRow(self::MSG_TABLE, 1);
@@ -196,7 +205,7 @@ class Spot extends Main
//Add pictures //Add pictures
if($bSuccess) { if($bSuccess) {
$asPics = $this->getPictures(); $asPics = $this->getPictures('taken_on');
//Sort messages and pictures chronologically //Sort messages and pictures chronologically
uasort($asPics, function($a, $b){return $a['unix_timestamp'] > $b['unix_timestamp'];}); uasort($asPics, function($a, $b){return $a['unix_timestamp'] > $b['unix_timestamp'];});
@@ -255,13 +264,13 @@ class Spot extends Main
$asMessages = $this->oDb->selectRows($asInfo); $asMessages = $this->oDb->selectRows($asInfo);
foreach($asMessages as $asMessage) foreach($asMessages as $asMessage)
{ {
$asMessage['unix_timestamp'] = (int) $asMessage['unix_timestamp'];
$asMessage['latitude'] = floatval($asMessage['latitude']); $asMessage['latitude'] = floatval($asMessage['latitude']);
$asMessage['longitude'] = floatval($asMessage['longitude']); $asMessage['longitude'] = floatval($asMessage['longitude']);
$asMessage['lat_dms'] = self::DecToDMS($asMessage['latitude'], 'lat'); $asMessage['lat_dms'] = self::DecToDMS($asMessage['latitude'], 'lat');
$asMessage['lon_dms'] = self::DecToDMS($asMessage['longitude'], 'lon'); $asMessage['lon_dms'] = self::DecToDMS($asMessage['longitude'], 'lon');
$asMessage['relative_time'] = Toolbox::getDateTimeDesc($asMessage['unix_timestamp'], 'fr');
$asMessage['formatted_time'] = date(self::FORMAT_TIME, $asMessage['unix_timestamp']); $this->addTimeStamp($asMessage, $asMessage['unix_timestamp']);
$asAllFeedMessages[] = $asMessage; $asAllFeedMessages[] = $asMessage;
} }
} }
@@ -269,34 +278,20 @@ class Spot extends Main
return $asAllFeedMessages; return $asAllFeedMessages;
} }
private function getPictures() private function getPictures($sTimeRefField)
{ {
$asPicPaths = glob(self::PIC_FOLDER.'*.{jpg,JPG,jpeg,JPEG,png,PNG}', GLOB_BRACE); $asPics = $this->oPicture->getPicsInfo();
$asValidPics = array();
$asPics = array(); foreach($asPics as &$asPic) {
foreach($asPicPaths as $sPicPath) $sTimeRef = $asPic[$sTimeRefField];
{ if($sTimeRef >= $this->oProject->getActivePeriod('from') && $sTimeRef <= $this->oProject->getActivePeriod('to')) {
//Finding picture timestamp $asPic['taken_on_formatted'] = date(self::FORMAT_TIME, strtotime($asPic['taken_on']));
$asPicInfo = self::getPicInfo($sPicPath); $this->addTimeStamp($asPic, strtotime($sTimeRef));
$iPicTimeStamp = $asPicInfo['timestamp']; $asValidPics[] = $asPic;
//Get/Create thumbnail
$sThumbnailPath = self::getPicThumbnail($sPicPath);
//Filter on valid time interval
if($iPicTimeStamp >= strtotime($this->oProject->getActivePeriod('from')) && $iPicTimeStamp <= strtotime($this->oProject->getActivePeriod('to'))) {
$asPics[] = array(
'path' => $sPicPath,
'thumb_path' => $sThumbnailPath,
'rotate' => $asPicInfo['rotate'],
'unix_timestamp'=> $iPicTimeStamp,
'formatted_time'=> date(self::FORMAT_TIME, $iPicTimeStamp),
'relative_time' => Toolbox::getDateTimeDesc($iPicTimeStamp, 'fr')
);
} }
} }
return $asPics;
return $asValidPics;
} }
private function getPosts() private function getPosts()
@@ -314,10 +309,9 @@ class Spot extends Main
foreach($asPosts as &$asPost) { foreach($asPosts as &$asPost) {
$iUnixTimeStamp = strtotime($asPost['timestamp']); $iUnixTimeStamp = strtotime($asPost['timestamp']);
$asPost['unix_timestamp'] = $iUnixTimeStamp;
$asPost['relative_time'] = Toolbox::getDateTimeDesc($iUnixTimeStamp, 'fr');
$asPost['formatted_time'] = date(self::FORMAT_TIME, $iUnixTimeStamp);
$asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']); $asPost['formatted_name'] = Toolbox::mb_ucwords($asPost['name']);
$this->addTimeStamp($asPost, $iUnixTimeStamp);
} }
return $asPosts; return $asPosts;
@@ -328,23 +322,28 @@ class Spot extends Main
return ($iTimeStamp * -1).'.'.$sPriority.$iDbId; return ($iTimeStamp * -1).'.'.$sPriority.$iDbId;
} }
private function addTimeStamp(&$asData, $iTime) {
$asData['unix_timestamp'] = (int) $iTime;
$asData['relative_time'] = Toolbox::getDateTimeDesc($iTime, 'fr');
$asData['formatted_time'] = date(self::FORMAT_TIME, $iTime);
}
public function getNewsFeed($iChunk=0) public function getNewsFeed($iChunk=0)
{ {
$asFeed = array(); $asFeed = array();
//Messages //Messages
$asMessages = $this->getSpotMessages(); $asMessages = $this->getSpotMessages();
foreach($asMessages as $asMessage) foreach($asMessages as $iIndex=>$asMessage)
{ {
$iMsgId = $asMessage[Db::getId(self::MSG_TABLE)]; $iId = self::getJsonId($asMessage['unix_timestamp'], '0', $asMessage[Db::getId(self::MSG_TABLE)]);
$iId = self::getJsonId($asMessage['unix_timestamp'], '0', $iMsgId);
$asFeed[$iId] = $asMessage; $asFeed[$iId] = $asMessage;
$asFeed[$iId]['type'] = 'message'; $asFeed[$iId]['type'] = 'message';
$asFeed[$iId]['displayed_id'] = $iMsgId; $asFeed[$iId]['displayed_id'] = 'N°'.$iIndex;
} }
//Pictures //Pictures
$asPics = $this->getPictures(); $asPics = $this->getPictures('added_on');
foreach($asPics as $iKey=>$asPic) foreach($asPics as $iKey=>$asPic)
{ {
$iId = self::getJsonId($asPic['unix_timestamp'], '1', $iKey); $iId = self::getJsonId($asPic['unix_timestamp'], '1', $iKey);
@@ -370,6 +369,10 @@ class Spot extends Main
return self::getJsonResult(true, '', $asFeed); return self::getJsonResult(true, '', $asFeed);
} }
public function syncPics() {
return $this->oPicture->syncFileFolder();
}
public function addPost($sName, $sPost) public function addPost($sName, $sPost)
{ {
$asData = array( $asData = array(
@@ -385,9 +388,9 @@ class Spot extends Main
public function upload() public function upload()
{ {
$this->oClassManagement->incClass('uploader', true); $this->oClassManagement->incClass('uploader', true);
$oUploader = new Uploader(array('image_versions'=>array(), 'accept_file_types'=>'/\.(gif|jpe?g|png)$/i')); $oUploader = new Uploader($this->oPicture);
$oUploader->init();
return $oUploader->getBody(); return self::getJsonResult(true, '');
} }
public function getTile($sMapId, $iX, $iY, $iZ) public function getTile($sMapId, $iX, $iY, $iZ)
@@ -432,54 +435,6 @@ class Spot extends Main
} }
} }
public static function getPicInfo($sPicPath)
{
$iPicTimeStamp = $iPicTakenTimeStamp = $iPicFileTimeStamp = 0;
$asExif = @exif_read_data($sPicPath, 0, true);
if(!$asExif) $asExif['FILE']['FileDateTime'] = filemtime($sPicPath);
//Timestamps
if(array_key_exists('EXIF', $asExif) && array_key_exists('DateTimeOriginal', $asExif['EXIF'])) $iPicTakenTimeStamp = strtotime($asExif['EXIF']['DateTimeOriginal']);
if(array_key_exists('FILE', $asExif) && array_key_exists('FileDateTime', $asExif['FILE'])) $iPicFileTimeStamp = $asExif['FILE']['FileDateTime'];
//Merge timestamps
$iPicTimeStamp = ($iPicTakenTimeStamp > 0)?$iPicTakenTimeStamp:$iPicFileTimeStamp;
//Time Zone
//if($iPicTimeStamp >= self::HONEYMOON_DATE_BEG && $iPicTimeStamp <= self::HONEYMOON_DATE_END) $iPicTimeStamp -= 60*60*(12+1); //timezone + daylight saving
//Orientation
if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) {
switch($asExif['IFD0']['Orientation'])
{
case 1: $sRotate = '0'; break; //None
case 3: $sRotate = '180'; break; //Flip over
case 6: $sRotate = '90'; break; //Clockwise
case 8: $sRotate = '-90'; break; //Trigo
default: $sRotate = $asExif['IFD0']['Orientation'];
}
}
else $sRotate = '0';
return array(
'timestamp' => $iPicTimeStamp,
'taken_ts' => $iPicTakenTimeStamp,
'file_ts' => $iPicFileTimeStamp,
'rotate' => $sRotate
);
}
public static function getPicThumbnail($sPicPath)
{
$sPicName = pathinfo($sPicPath, PATHINFO_BASENAME);
$sThumbPath = self::THUMB_FOLDER.$sPicName;
if(!file_exists($sThumbPath)) $asThumbInfo = ToolBox::createThumbnail($sPicPath, 400, 0, $sThumbPath/*, false, array('jpg', 'jpeg', 'gif', 'png'), true*/);
else $asThumbInfo = array('error'=>'', 'out'=>$sThumbPath);
return ($asThumbInfo['error']=='')?$asThumbInfo['out']:$sPicPath;
}
public static function DecToDMS($dValue, $sType='lat') { public static function DecToDMS($dValue, $sType='lat') {
if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S';
else $sDirection = ($dValue >= 0)?'E':'W'; else $sDirection = ($dValue >= 0)?'E':'W';

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,8 @@ if($sAction!='')
{ {
switch($sAction) switch($sAction)
{ {
case 'messages': case 'markers':
$sResult = $oSpot->getMessages(); $sResult = $oSpot->getMarkers();
break; break;
case 'feed': case 'feed':
$sResult = $oSpot->getNewsFeed($iChunk); $sResult = $oSpot->getNewsFeed($iChunk);
@@ -54,6 +54,9 @@ if($sAction!='')
/*case 'sql': /*case 'sql':
$sResult = $oSpot->getDbBuildScript(); $sResult = $oSpot->getDbBuildScript();
break;*/ break;*/
case 'sync_pics':
$sResult = $oSpot->syncPics();
break;
default: default:
$sResult = Spot::getJsonResult(false, Spot::NOT_FOUND); $sResult = Spot::getJsonResult(false, Spot::NOT_FOUND);
} }

View File

@@ -69,14 +69,15 @@ function initProject(sProjectCodeName){
self.tmp('first_exec', false); self.tmp('first_exec', false);
self.vars('project', self.vars(['projects', sProjectCodeName])); self.vars('project', self.vars(['projects', sProjectCodeName]));
//Spot Messages
$.when( $.when(
//Markers: Spot Messages & Pictures
self.get( self.get(
'messages', 'markers',
function(){}, function(){},
{project_id: self.vars(['project', 'id'])}, {project_id: self.vars(['project', 'id'])},
function(e){console.log(e);} function(e){console.log(e);}
), ),
//Project Geojson: Hike track
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: self.vars(['project', 'geofile']), url: self.vars(['project', 'geofile']),
@@ -101,6 +102,8 @@ function initPosts() {
}; };
getPost(asPoster).appendTo($Poster.show()); getPost(asPoster).appendTo($Poster.show());
autosize($('#post'));
$('#submit').click(function(){ $('#submit').click(function(){
if($Poster.checkForm()) if($Poster.checkForm())
{ {
@@ -167,7 +170,7 @@ function initSpotMessages(aoMessages, aoTracks) {
}).addTo(oMap); }).addTo(oMap);
//Centering map //Centering map
if(self.vars(['project', 'mode'])==self.consts.modes.blog) if(self.vars(['project', 'mode'])==self.consts.modes.blog && aoMessages.length > 0)
{ {
//Zoom on last message //Zoom on last message
var oLastMsg = aoMessages[aoMessages.length-1]; var oLastMsg = aoMessages[aoMessages.length-1];
@@ -233,7 +236,7 @@ function initSpotMessages(aoMessages, aoTracks) {
if(oMsg.pics) { if(oMsg.pics) {
var $Pics = $('<div>', {'class':'pics'}); var $Pics = $('<div>', {'class':'pics'});
$.each(oMsg.pics, function(iKey, asPic){ $.each(oMsg.pics, function(iKey, asPic){
$Pics.append($('<a>', {href: asPic.path, 'data-lightbox': self.consts.title, 'data-title': asPic.formatted_time}) $Pics.append($('<a>', {href: asPic.pic_path, 'data-lightbox': self.consts.title, 'data-title': asPic.formatted_time})
.append($('<img>', {'src': asPic.thumb_path}))); .append($('<img>', {'src': asPic.thumb_path})));
}); });
$Tooltip $Tooltip
@@ -385,7 +388,7 @@ function getPost(asPost) {
break; break;
case 'picture': case 'picture':
var $Image = $('<img>', {'src': asPost.thumb_path/*, 'style':'transform:rotate('+asPost.rotate+'deg);'*/}); var $Image = $('<img>', {'src': asPost.thumb_path/*, 'style':'transform:rotate('+asPost.rotate+'deg);'*/});
$Body = $('<a>', {href: asPost.path, 'data-lightbox': self.consts.title, 'data-title': sAbsTime}).append($Image); $Body = $('<a>', {href: asPost.pic_path, 'data-lightbox': self.consts.title, 'data-title': 'Photo ajouté le '+sAbsTime+' (prise le '+asPost.taken_on_formatted+')'}).append($Image);
break; break;
case 'post': case 'post':
$Body = $('<div>') $Body = $('<div>')
@@ -394,7 +397,7 @@ function getPost(asPost) {
break; break;
case 'poster': case 'poster':
$Body = $('<p>', {'class':'message'}) $Body = $('<p>', {'class':'message'})
.append($('<input>', {type:'text', id:'post', name:'post', placeholder:'Message'})) .append($('<textarea>', {id:'post', name:'post', placeholder:'Message', 'class':'autoExpand', rows:'1'}))
.append($('<input>', {type:'text', id:'name', name:'name', placeholder:'Nom'})) .append($('<input>', {type:'text', id:'name', name:'name', placeholder:'Nom'}))
.append($('<button>', {type:'button', id:'submit', name:'submit'}).addIcon('fa-send')); .append($('<button>', {type:'button', id:'submit', name:'submit'}).addIcon('fa-send'));
break; break;

View File

@@ -8,25 +8,29 @@
<script type="text/javascript"> <script type="text/javascript">
oSpot.pageInit = function(asHash) oSpot.pageInit = function(asHash)
{ {
$('#fileupload') var asProject = self.vars(['projects', self.vars('default_project_codename')]);
.attr('data-url', self.getActionLink('upload')) if(asProject.mode == self.consts.modes.blog) {
.fileupload({ $('#fileupload')
dataType: 'json', .attr('data-url', self.getActionLink('upload'))
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, .fileupload({
done: function (e, data) { dataType: 'json',
var $Status = $('#status'); acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
$.each(data.result.files, function(iKey, oFile) { done: function (e, asResult) {
var sMsg = ('error' in oFile)?oFile.error:(oFile.name+" uploaded succesfully"); var $Status = $('#status');
$Status.append($('<p>').text(sMsg)); $.each(asResult.files, function(iKey, oFile) {
}); var sMsg = ('error' in oFile)?oFile.error:(oFile.name+" uploaded successfully");
}, $Status.append($('<p>').text(sMsg));
progressall: function (e, data) { });
var progress = parseInt(data.loaded / data.total * 100, 10); },
$('#progress .bar').css( progressall: function (e, data) {
'width', var progress = parseInt(data.loaded / data.total * 100, 10);
progress + '%' $('#progress .bar').css(
); 'width',
} progress + '%'
}); );
}
});
}
else $('#messages').empty().append('Le projet "'+asProject.name+'" n\'est pas en mode blog. Aucun upload possible.');
}; };
</script> </script>

File diff suppressed because one or more lines are too long

View File

@@ -27,3 +27,18 @@
.flicker { .flicker {
@include animate(fadeIn 0.8s infinite alternate); @include animate(fadeIn 0.8s infinite alternate);
} }
/* Fonts */
@import url('https://fonts.googleapis.com/css?family=Ubuntu:400,700&subset=latin-ext');
body, textarea, input, button {
font-size: 14px;
font-family: 'Ubuntu', sans-serif;
}
/* Common objects */
textarea {
resize: none;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -64,7 +64,7 @@
text-align: center; text-align: center;
line-height: 44px; line-height: 44px;
text-decoration: none; text-decoration: none;
color: #888; color: #999;
text-shadow: 0px 1px 1px rgba(0,0,0,0.8); text-shadow: 0px 1px 1px rgba(0,0,0,0.8);
background: none; background: none;
@extend .fa; @extend .fa;
@@ -112,7 +112,7 @@
width: calc(30% - 1em); width: calc(30% - 1em);
z-index: 999; z-index: 999;
input, button { input, textarea, button {
border: none; border: none;
padding: 0.5em 1em; padding: 0.5em 1em;
background: #F7F7F7; background: #F7F7F7;
@@ -129,7 +129,6 @@
} }
#posts { #posts {
font-family: Arial;
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
@@ -137,7 +136,7 @@
#poster { #poster {
input, button { input, textarea, button {
border-radius: 3px; border-radius: 3px;
background-color: #d9deff; background-color: #d9deff;
color: #323268; color: #323268;

2
todo
View File

@@ -1,8 +1,6 @@
To Do List To Do List
---------- ----------
- Elevation chart - Elevation chart
- Table for images
- Device/Spot Class - Device/Spot Class
- Manage projects.timezone - Manage projects.timezone
- Remove files2/ on server - Remove files2/ on server
- replace message ID with project ID / Message ID on display