$ git clone http://thingshare.ion.nu/thingshare.git
commit 44b94fb1c0a96724bba70deb59848bf3eb6dd95a
Author: Alicia <...>
Date:   Fri Mar 20 23:51:25 2020 +0100

    Handle timezones.

diff --git a/db.php b/db.php
index cd82d63..02f47b1 100644
--- a/db.php
+++ b/db.php
@@ -38,6 +38,7 @@ define('ACCOUNT_BANNED', 1);
 define('ACCOUNT_EMAILUNVERIFIED', 2);
 
 $db=mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
+date_default_timezone_set('UTC'); // Anything involving the database should use UTC time
 
 function getoption($name, $default=false)
 {
diff --git a/head.php b/head.php
index 21f7f8c..e1b02d9 100644
--- a/head.php
+++ b/head.php
@@ -50,6 +50,7 @@ $search=htmlentities(isset($_GET['q'])?$_GET['q']:'');
 <head>
   <title><?=NODENAME?></title>
   <link rel="stylesheet" href="<?=BASEURL?>/style.css" type="text/css" />
+  <script src="<?=BASEURL?>/time.js"></script>
 </head>
 <body>
   <div id="logo" title="Yes this needs a logo or something. Got any art skills?"></div>
diff --git a/messages.php b/messages.php
index 5e13479..edee07d 100644
--- a/messages.php
+++ b/messages.php
@@ -89,7 +89,7 @@ if($error=='' && isset($_POST['msg']) && isset($_POST['subject']) && ($path[2]!=
   }else{
     $info=_('Message sent');
     // Update 'latest' on messages which are now old
-    mysqli_query($db, 'update messages set latest=false where chain="'.$chain.'" and user='.(int)$_SESSION['id'].' and id!='.$id);
+    mysqli_query($db, 'update messages set latest=false where chain="'.$chain.'" and user='.(int)$_SESSION['id'].' and id!='.$id.' and sent<"'.$timestamp.'"');
   }
   }} // Error checks
 }
@@ -103,14 +103,14 @@ if(!isset($path[2]) || $path[2]=='') // Overview
   while($row=mysqli_fetch_assoc($res))
   {
     $user=(($row['recipient']==$_SESSION['name'].'@'.DOMAIN)?$row['sender']:$row['recipient']);
-    $user='<a href="'.BASEURL.'/user/'.urlencode($user).'" title="'.htmlentities($user).'">'.htmlentities(getdisplayname($user)).'</a>';
+    $user='<a href="'.BASEURL.'/user/'.$user.'" title="'.htmlentities($user).'">'.htmlentities(getdisplayname($user)).'</a>';
     $subjectline=htmlentities($row['subject']);
     $chain=htmlentities($row['chain']);
     $aclass=($row['msgread']?'':' class="highlight"'); // Highlight link if unread
     $messages.='<tr>';
     $messages.='  <td>'.$user.'</td>';
     $messages.='  <td><a href="'.BASEURL.'/messages/'.$chain.'"'.$aclass.'>'.$subjectline.'</a></td>';
-    $messages.='  <td>'.htmlentities($row['sent']).'</td>';
+    $messages.='  <td><span class="time">'.htmlentities($row['sent']).'</span></td>';
     $messages.='</tr>';
   }
 }
@@ -126,7 +126,7 @@ elseif($error=='' && $path[2]!='new') // Thread view
     $msg=$md->text($row['message']);
     $time=htmlentities($row['sent']);
 // TODO: CSS for this
-    $messages.='<div class="message'.($row['msgread']?'':' message_unread').'"><div class="message_sender"><a href="'.BASEURL.'/user/'.$sender.'" title="'.$sender.'">'.$displayname.'</a> '.$time.'</div>'.$msg.'</div>';
+    $messages.='<div class="message'.($row['msgread']?'':' message_unread').'"><div class="message_sender"><a href="'.BASEURL.'/user/'.$sender.'" title="'.$sender.'">'.$displayname.'</a> <span class="time">'.$time.'</span></div>'.$msg.'</div>';
   }
   mysqli_query($db, 'update messages set msgread=true where user='.(int)$_SESSION['id'].' and chain="'.$chain.'" order by sent asc');
 // TODO: Option to block user
diff --git a/thing.php b/thing.php
index f2a0b68..a82629a 100644
--- a/thing.php
+++ b/thing.php
@@ -57,6 +57,6 @@ foreach($thingobj['files'] as $file)
 }
 ?>
 <h1><?=$name?> <small class="subheader">by <a href="<?=BASEURL?>/user/<?=$thingobj['by']['name']?>@<?=$thing[1]?>" title="<?=$thingobj['by']['name']?>@<?=$thing[1]?>"><?=htmlentities($thingobj['by']['displayname'])?></a></small></h1>
-<small><?=sprintf(_('Published on %s under the license %s'), htmlentities($thingobj['date']), $license)?></small><br />
+<small><?=sprintf(_('Published on %s under the license %s'), '<span class="time">'.htmlentities($thingobj['date']).'</span>', $license)?></small><br />
 <?=$description?><br />
 <?=$files?>
diff --git a/time.js b/time.js
new file mode 100644
index 0000000..3fadaff
--- /dev/null
+++ b/time.js
@@ -0,0 +1,25 @@
+/*
+    This file is part of Thingshare, a federated system for sharing data for home manufacturing (e.g. 3D models to 3D print)
+    https://thingshare.ion.nu/
+    Copyright (C) 2020  Alicia <...>
+
+    See /COPYING for license text (AGPLv3+)
+*/
+window.addEventListener('load', function()
+{
+  // Convert times to local time
+  var pad=function(x)
+  {
+    x=x.toString();
+    if(x.length<2){x='0'+x;}
+    return x;
+  }
+  var offset=(new Date()).getTimezoneOffset();
+  var times=document.getElementsByClassName('time');
+  for(var i=0; i<times.length; ++i)
+  {
+    var t=new Date(times[i].textContent);
+    t.setTime(t.getTime()-offset*60000); // Time in milliseconds, offset in minutes
+    times[i].textContent=t.getFullYear()+'-'+pad(t.getMonth()+1)+'-'+pad(t.getDate())+' '+t.getHours()+':'+pad(t.getMinutes())+':'+pad(t.getSeconds());
+  }
+});