Merge branch 'friendica:2022.12-rc' into new_image_presentation
This commit is contained in:
commit
23f31883f5
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2022.12-rc (Giant Rhubarb)
|
-- Friendica 2022.12-rc (Giant Rhubarb)
|
||||||
-- DB_UPDATE_VERSION 1500
|
-- DB_UPDATE_VERSION 1501
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
||||||
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT 'XMPP address',
|
`xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT 'XMPP address',
|
||||||
`matrix` varchar(255) NOT NULL DEFAULT '' COMMENT 'Matrix address',
|
`matrix` varchar(255) NOT NULL DEFAULT '' COMMENT 'Matrix address',
|
||||||
`avatar` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
`avatar` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
||||||
|
`blurhash` varbinary(255) COMMENT 'BlurHash representation of the avatar',
|
||||||
`header` varbinary(383) COMMENT 'Header picture',
|
`header` varbinary(383) COMMENT 'Header picture',
|
||||||
`url` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
`url` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
||||||
`nurl` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
`nurl` varbinary(383) NOT NULL DEFAULT '' COMMENT '',
|
||||||
|
@ -1297,6 +1298,9 @@ CREATE TABLE IF NOT EXISTS `post-link` (
|
||||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||||
`url` varbinary(511) NOT NULL COMMENT 'External URL',
|
`url` varbinary(511) NOT NULL COMMENT 'External URL',
|
||||||
`mimetype` varchar(60) COMMENT '',
|
`mimetype` varchar(60) COMMENT '',
|
||||||
|
`height` smallint unsigned COMMENT 'Height of the media',
|
||||||
|
`width` smallint unsigned COMMENT 'Width of the media',
|
||||||
|
`blurhash` varbinary(255) COMMENT 'BlurHash representation of the link',
|
||||||
PRIMARY KEY(`id`),
|
PRIMARY KEY(`id`),
|
||||||
UNIQUE INDEX `uri-id-url` (`uri-id`,`url`),
|
UNIQUE INDEX `uri-id-url` (`uri-id`,`url`),
|
||||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||||
|
|
|
@ -21,6 +21,7 @@ Fields
|
||||||
| xmpp | XMPP address | varchar(255) | NO | | | |
|
| xmpp | XMPP address | varchar(255) | NO | | | |
|
||||||
| matrix | Matrix address | varchar(255) | NO | | | |
|
| matrix | Matrix address | varchar(255) | NO | | | |
|
||||||
| avatar | | varbinary(383) | NO | | | |
|
| avatar | | varbinary(383) | NO | | | |
|
||||||
|
| blurhash | BlurHash representation of the avatar | varbinary(255) | YES | | NULL | |
|
||||||
| header | Header picture | varbinary(383) | YES | | NULL | |
|
| header | Header picture | varbinary(383) | YES | | NULL | |
|
||||||
| url | | varbinary(383) | NO | | | |
|
| url | | varbinary(383) | NO | | | |
|
||||||
| nurl | | varbinary(383) | NO | | | |
|
| nurl | | varbinary(383) | NO | | | |
|
||||||
|
|
|
@ -7,11 +7,14 @@ Fields
|
||||||
------
|
------
|
||||||
|
|
||||||
| Field | Description | Type | Null | Key | Default | Extra |
|
| Field | Description | Type | Null | Key | Default | Extra |
|
||||||
| -------- | --------------------------------------------------------- | -------------- | ---- | --- | ------- | -------------- |
|
| -------- | --------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- |
|
||||||
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
|
||||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
|
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
|
||||||
| url | External URL | varbinary(511) | NO | | NULL | |
|
| url | External URL | varbinary(511) | NO | | NULL | |
|
||||||
| mimetype | | varchar(60) | YES | | NULL | |
|
| mimetype | | varchar(60) | YES | | NULL | |
|
||||||
|
| height | Height of the media | smallint unsigned | YES | | NULL | |
|
||||||
|
| width | Width of the media | smallint unsigned | YES | | NULL | |
|
||||||
|
| blurhash | BlurHash representation of the link | varbinary(255) | YES | | NULL | |
|
||||||
|
|
||||||
Indexes
|
Indexes
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -90,6 +90,8 @@ class Avatar
|
||||||
$filename = self::getFilename($contact['url']);
|
$filename = self::getFilename($contact['url']);
|
||||||
$timestamp = time();
|
$timestamp = time();
|
||||||
|
|
||||||
|
$fields['blurhash'] = $image->getBlurHash();
|
||||||
|
|
||||||
$fields['photo'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_SMALL, $timestamp);
|
$fields['photo'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_SMALL, $timestamp);
|
||||||
$fields['thumb'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_THUMB, $timestamp);
|
$fields['thumb'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_THUMB, $timestamp);
|
||||||
$fields['micro'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_MICRO, $timestamp);
|
$fields['micro'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_MICRO, $timestamp);
|
||||||
|
|
|
@ -59,7 +59,7 @@ class ExternalResource implements ICanReadFromStorage
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception);
|
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception);
|
||||||
}
|
}
|
||||||
if ($fetchResult->isSuccess()) {
|
if (!empty($fetchResult) && $fetchResult->isSuccess()) {
|
||||||
Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
|
Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
|
||||||
return $fetchResult->getBody();
|
return $fetchResult->getBody();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,11 +34,15 @@ use Friendica\Core\Worker;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||||
|
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Network\Probe;
|
use Friendica\Network\Probe;
|
||||||
|
use Friendica\Object\Image;
|
||||||
use Friendica\Protocol\Activity;
|
use Friendica\Protocol\Activity;
|
||||||
use Friendica\Protocol\ActivityPub;
|
use Friendica\Protocol\ActivityPub;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
use Friendica\Util\HTTPSignature;
|
||||||
use Friendica\Util\Images;
|
use Friendica\Util\Images;
|
||||||
use Friendica\Util\Network;
|
use Friendica\Util\Network;
|
||||||
use Friendica\Util\Proxy;
|
use Friendica\Util\Proxy;
|
||||||
|
@ -2193,7 +2197,7 @@ class Contact
|
||||||
*/
|
*/
|
||||||
public static function updateAvatar(int $cid, string $avatar, bool $force = false, bool $create_cache = false)
|
public static function updateAvatar(int $cid, string $avatar, bool $force = false, bool $create_cache = false)
|
||||||
{
|
{
|
||||||
$contact = DBA::selectFirst('contact', ['uid', 'avatar', 'photo', 'thumb', 'micro', 'xmpp', 'addr', 'nurl', 'url', 'network', 'uri-id'],
|
$contact = DBA::selectFirst('contact', ['uid', 'avatar', 'photo', 'thumb', 'micro', 'blurhash', 'xmpp', 'addr', 'nurl', 'url', 'network', 'uri-id'],
|
||||||
['id' => $cid, 'self' => false]);
|
['id' => $cid, 'self' => false]);
|
||||||
if (!DBA::isResult($contact)) {
|
if (!DBA::isResult($contact)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2203,8 +2207,19 @@ class Contact
|
||||||
|
|
||||||
// Only update the cached photo links of public contacts when they already are cached
|
// Only update the cached photo links of public contacts when they already are cached
|
||||||
if (($uid == 0) && !$force && empty($contact['thumb']) && empty($contact['micro']) && !$create_cache) {
|
if (($uid == 0) && !$force && empty($contact['thumb']) && empty($contact['micro']) && !$create_cache) {
|
||||||
if ($contact['avatar'] != $avatar) {
|
if (($contact['avatar'] != $avatar) || empty($contact['blurhash'])) {
|
||||||
self::update(['avatar' => $avatar], ['id' => $cid]);
|
$update_fields = ['avatar' => $avatar];
|
||||||
|
$fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]);
|
||||||
|
|
||||||
|
$img_str = $fetchResult->getBody();
|
||||||
|
if (!empty($img_str)) {
|
||||||
|
$image = new Image($img_str, Images::getMimeTypeByData($img_str));
|
||||||
|
if ($image->isValid()) {
|
||||||
|
$update_fields['blurhash'] = $image->getBlurHash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self::update($update_fields, ['id' => $cid]);
|
||||||
Logger::info('Only update the avatar', ['id' => $cid, 'avatar' => $avatar, 'contact' => $contact]);
|
Logger::info('Only update the avatar', ['id' => $cid, 'avatar' => $avatar, 'contact' => $contact]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2275,7 +2290,7 @@ class Contact
|
||||||
if ($update) {
|
if ($update) {
|
||||||
$photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
|
$photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
|
||||||
if ($photos) {
|
if ($photos) {
|
||||||
$fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'avatar-date' => DateTimeFormat::utcNow()];
|
$fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'blurhash' => $photos[3], 'avatar-date' => DateTimeFormat::utcNow()];
|
||||||
$update = !empty($fields);
|
$update = !empty($fields);
|
||||||
Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]);
|
Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -313,6 +313,28 @@ class Photo
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a photo array for a given image data string
|
||||||
|
*
|
||||||
|
* @param string $image_data Image data
|
||||||
|
* @param string $mimetype Image mime type. Is guessed by file name when empty.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function createPhotoForImageData(string $image_data, string $mimetype = ''): array
|
||||||
|
{
|
||||||
|
$fields = self::getFields();
|
||||||
|
$values = array_fill(0, count($fields), '');
|
||||||
|
|
||||||
|
$photo = array_combine($fields, $values);
|
||||||
|
$photo['data'] = $image_data;
|
||||||
|
$photo['type'] = $mimetype ?: Images::getMimeTypeByData($image_data);
|
||||||
|
$photo['cacheable'] = false;
|
||||||
|
|
||||||
|
return $photo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a photo array for a system resource image
|
* Construct a photo array for a system resource image
|
||||||
*
|
*
|
||||||
|
@ -647,7 +669,11 @@ class Photo
|
||||||
$micro = Contact::getDefaultAvatar($contact, Proxy::SIZE_MICRO);
|
$micro = Contact::getDefaultAvatar($contact, Proxy::SIZE_MICRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$image_url, $thumb, $micro];
|
$photo = DBA::selectFirst(
|
||||||
|
'photo', ['blurhash'], ['uid' => $uid, 'contact-id' => $cid, 'scale' => 4, 'photo-type' => self::CONTACT_AVATAR]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [$image_url, $thumb, $micro, $photo['blurhash']];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,10 @@ use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||||
|
use Friendica\Util\HTTPSignature;
|
||||||
|
use Friendica\Util\Images;
|
||||||
use Friendica\Util\Proxy;
|
use Friendica\Util\Proxy;
|
||||||
|
use Friendica\Object\Image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Link
|
* Class Link
|
||||||
|
@ -73,11 +76,13 @@ class Link
|
||||||
$id = $link['id'];
|
$id = $link['id'];
|
||||||
Logger::info('Found', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
|
Logger::info('Found', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
|
||||||
} else {
|
} else {
|
||||||
$mime = self::fetchMimeType($url);
|
$fields = self::fetchMimeType($url);
|
||||||
|
$fields['uri-id'] = $uriId;
|
||||||
|
$fields['url'] = $url;
|
||||||
|
|
||||||
DBA::insert('post-link', ['uri-id' => $uriId, 'url' => $url, 'mimetype' => $mime], Database::INSERT_IGNORE);
|
DBA::insert('post-link', $fields, Database::INSERT_IGNORE);
|
||||||
$id = DBA::lastInsertId();
|
$id = DBA::lastInsertId();
|
||||||
Logger::info('Inserted', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
|
Logger::info('Inserted', $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($id)) {
|
if (empty($id)) {
|
||||||
|
@ -114,19 +119,28 @@ class Link
|
||||||
*
|
*
|
||||||
* @param string $url URL to fetch
|
* @param string $url URL to fetch
|
||||||
* @param string $accept Comma-separated list of expected response MIME type(s)
|
* @param string $accept Comma-separated list of expected response MIME type(s)
|
||||||
* @return string Discovered MIME type or empty string on failure
|
* @return array Discovered MIME type and blurhash or empty array on failure
|
||||||
*/
|
*/
|
||||||
private static function fetchMimeType(string $url, string $accept = HttpClientAccept::DEFAULT): string
|
private static function fetchMimeType(string $url, string $accept = HttpClientAccept::DEFAULT): array
|
||||||
{
|
{
|
||||||
$timeout = DI::config()->get('system', 'xrd_timeout');
|
$timeout = DI::config()->get('system', 'xrd_timeout');
|
||||||
|
|
||||||
$curlResult = DI::httpClient()->head($url, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
|
$curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
|
||||||
|
if (!$curlResult->isSuccess()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]];
|
||||||
|
|
||||||
if ($curlResult->isSuccess() && empty($media['mimetype'])) {
|
$img_str = $curlResult->getBody();
|
||||||
return $curlResult->getHeader('Content-Type')[0] ?? '';
|
$image = new Image($img_str, Images::getMimeTypeByData($img_str));
|
||||||
|
if ($image->isValid()) {
|
||||||
|
$fields['mimetype'] = $image->getType();
|
||||||
|
$fields['width'] = $image->getWidth();
|
||||||
|
$fields['height'] = $image->getHeight();
|
||||||
|
$fields['blurhash'] = $image->getBlurHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -440,6 +440,12 @@ class UserNotification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only check on posts by the user itself
|
||||||
|
$cdata = Contact::getPublicAndUserContactID($item['contact-id'], $item['uid']);
|
||||||
|
if (empty($cdata['user']) || ($item['author-id'] != $cdata['public'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the contact posted or shared something directly
|
// Check if the contact posted or shared something directly
|
||||||
if (DBA::exists('contact', ['id' => $item['contact-id'], 'notify_new_posts' => true])) {
|
if (DBA::exists('contact', ['id' => $item['contact-id'], 'notify_new_posts' => true])) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -137,7 +137,7 @@ abstract class BaseUsers extends BaseModeration
|
||||||
$user['account_type'] = ($user['page_flags_raw'] == 0) ? $account_types[$user['account-type']] : '';
|
$user['account_type'] = ($user['page_flags_raw'] == 0) ? $account_types[$user['account-type']] : '';
|
||||||
|
|
||||||
$user['register_date'] = Temporal::getRelativeDate($user['register_date']);
|
$user['register_date'] = Temporal::getRelativeDate($user['register_date']);
|
||||||
$user['login_date'] = Temporal::getRelativeDate($user['last-activity']);
|
$user['login_date'] = Temporal::getRelativeDate($user['last-activity'], null, false);
|
||||||
$user['lastitem_date'] = Temporal::getRelativeDate($user['last-item']);
|
$user['lastitem_date'] = Temporal::getRelativeDate($user['last-item']);
|
||||||
$user['is_admin'] = in_array($user['email'], $adminlist);
|
$user['is_admin'] = in_array($user['email'], $adminlist);
|
||||||
$user['is_deletable'] = !$user['account_removed'] && intval($user['uid']) != $this->session->getLocalUserId();
|
$user['is_deletable'] = !$user['account_removed'] && intval($user['uid']) != $this->session->getLocalUserId();
|
||||||
|
|
|
@ -285,14 +285,14 @@ class Photo extends BaseModule
|
||||||
|
|
||||||
return MPhoto::createPhotoForExternalResource($media['url'], (int)DI::userSession()->getLocalUserId(), $media['mimetype'], $media['blurhash'], $media['width'], $media['height']);
|
return MPhoto::createPhotoForExternalResource($media['url'], (int)DI::userSession()->getLocalUserId(), $media['mimetype'], $media['blurhash'], $media['width'], $media['height']);
|
||||||
case 'link':
|
case 'link':
|
||||||
$link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $id]);
|
$link = DBA::selectFirst('post-link', ['url', 'mimetype', 'blurhash', 'width', 'height'], ['id' => $id]);
|
||||||
if (empty($link)) {
|
if (empty($link)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MPhoto::createPhotoForExternalResource($link['url'], (int)DI::userSession()->getLocalUserId(), $link['mimetype'] ?? '');
|
return MPhoto::createPhotoForExternalResource($link['url'], (int)DI::userSession()->getLocalUserId(), $link['mimetype'] ?? '', $link['blurhash'] ?? '', $link['width'] ?? 0, $link['height'] ?? 0);
|
||||||
case 'contact':
|
case 'contact':
|
||||||
$fields = ['uid', 'uri-id', 'url', 'nurl', 'avatar', 'photo', 'xmpp', 'addr', 'network', 'failed', 'updated'];
|
$fields = ['uid', 'uri-id', 'url', 'nurl', 'avatar', 'photo', 'blurhash', 'xmpp', 'addr', 'network', 'failed', 'updated'];
|
||||||
$contact = Contact::getById($id, $fields);
|
$contact = Contact::getById($id, $fields);
|
||||||
if (empty($contact)) {
|
if (empty($contact)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -364,7 +364,11 @@ class Photo extends BaseModule
|
||||||
Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]);
|
Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (empty($mimetext)) {
|
if (empty($mimetext) && !empty($contact['blurhash'])) {
|
||||||
|
$image = New Image('', 'image/png');
|
||||||
|
$image->getFromBlurHash($contact['blurhash'], $customsize, $customsize);
|
||||||
|
return MPhoto::createPhotoForImageData($image->asString());
|
||||||
|
} elseif (empty($mimetext)) {
|
||||||
if ($customsize <= Proxy::PIXEL_MICRO) {
|
if ($customsize <= Proxy::PIXEL_MICRO) {
|
||||||
$url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_MICRO);
|
$url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_MICRO);
|
||||||
} elseif ($customsize <= Proxy::PIXEL_THUMB) {
|
} elseif ($customsize <= Proxy::PIXEL_THUMB) {
|
||||||
|
@ -373,7 +377,7 @@ class Photo extends BaseModule
|
||||||
$url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_SMALL);
|
$url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_SMALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MPhoto::createPhotoForExternalResource($url, 0, $mimetext);
|
return MPhoto::createPhotoForExternalResource($url, 0, $mimetext, $contact['blurhash'], $customsize, $customsize);
|
||||||
case 'header':
|
case 'header':
|
||||||
$fields = ['uid', 'url', 'header', 'network', 'gsid'];
|
$fields = ['uid', 'url', 'header', 'network', 'gsid'];
|
||||||
$contact = Contact::getById($id, $fields);
|
$contact = Contact::getById($id, $fields);
|
||||||
|
|
|
@ -307,11 +307,12 @@ class Temporal
|
||||||
*
|
*
|
||||||
* @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS)
|
* @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS)
|
||||||
* @param string $format (optional) Parsed with sprintf()
|
* @param string $format (optional) Parsed with sprintf()
|
||||||
|
* @param bool $compare_time Compare date (false) or date and time (true). "true" is default.
|
||||||
* <tt>%1$d %2$s ago</tt>, e.g. 22 hours ago, 1 minute ago
|
* <tt>%1$d %2$s ago</tt>, e.g. 22 hours ago, 1 minute ago
|
||||||
*
|
*
|
||||||
* @return string with relative date
|
* @return string with relative date
|
||||||
*/
|
*/
|
||||||
public static function getRelativeDate(string $posted_date = null, string $format = null): string
|
public static function getRelativeDate(string $posted_date = null, string $format = null, bool $compare_time = true): string
|
||||||
{
|
{
|
||||||
if (empty($posted_date) || $posted_date <= DBA::NULL_DATETIME) {
|
if (empty($posted_date) || $posted_date <= DBA::NULL_DATETIME) {
|
||||||
return DI::l10n()->t('never');
|
return DI::l10n()->t('never');
|
||||||
|
@ -324,11 +325,18 @@ class Temporal
|
||||||
return DI::l10n()->t('never');
|
return DI::l10n()->t('never');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$now = time();
|
||||||
|
|
||||||
|
if (!$compare_time) {
|
||||||
|
$now = mktime(0, 0, 0, date('m', $now), date('d', $now), date('Y', $now));
|
||||||
|
$abs = mktime(0, 0, 0, date('m', $abs), date('d', $abs), date('Y', $abs));
|
||||||
|
}
|
||||||
|
|
||||||
$isfuture = false;
|
$isfuture = false;
|
||||||
$etime = time() - $abs;
|
$etime = $now - $abs;
|
||||||
|
|
||||||
if ($etime < 1 && $etime >= 0) {
|
if ($etime < 1 && $etime >= 0) {
|
||||||
return DI::l10n()->t('less than a second ago');
|
return $compare_time ? DI::l10n()->t('less than a second ago') : DI::l10n()->t('today');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($etime < 0){
|
if ($etime < 0){
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1500);
|
define('DB_UPDATE_VERSION', 1501);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -186,6 +186,7 @@ return [
|
||||||
"xmpp" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "XMPP address"],
|
"xmpp" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "XMPP address"],
|
||||||
"matrix" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Matrix address"],
|
"matrix" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Matrix address"],
|
||||||
"avatar" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
"avatar" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
|
"blurhash" => ["type" => "varbinary(255)", "comment" => "BlurHash representation of the avatar"],
|
||||||
"header" => ["type" => "varbinary(383)", "comment" => "Header picture"],
|
"header" => ["type" => "varbinary(383)", "comment" => "Header picture"],
|
||||||
"url" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
"url" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
"nurl" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
"nurl" => ["type" => "varbinary(383)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
|
@ -1323,6 +1324,9 @@ return [
|
||||||
"uri-id" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
|
"uri-id" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
|
||||||
"url" => ["type" => "varbinary(511)", "not null" => "1", "comment" => "External URL"],
|
"url" => ["type" => "varbinary(511)", "not null" => "1", "comment" => "External URL"],
|
||||||
"mimetype" => ["type" => "varchar(60)", "comment" => ""],
|
"mimetype" => ["type" => "varchar(60)", "comment" => ""],
|
||||||
|
"height" => ["type" => "smallint unsigned", "comment" => "Height of the media"],
|
||||||
|
"width" => ["type" => "smallint unsigned", "comment" => "Width of the media"],
|
||||||
|
"blurhash" => ["type" => "varbinary(255)", "comment" => "BlurHash representation of the link"],
|
||||||
],
|
],
|
||||||
"indexes" => [
|
"indexes" => [
|
||||||
"PRIMARY" => ["id"],
|
"PRIMARY" => ["id"],
|
||||||
|
|
Loading…
Reference in a new issue