feat(federation): Support the avatar

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2024-02-21 13:04:38 +01:00
parent 78dd420520
commit 9d3f685f55
No known key found for this signature in database
GPG key ID: 74434EFE0D2E2205
5 changed files with 101 additions and 2 deletions

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24" version="1.1">
<circle r="12" cx="12" cy="12" fill="#6B6B6B"/>
<path fill="#fff" d="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24" version="1.1">
<circle r="12" cx="12" cy="12" fill="#999999"/>
<path fill="#000" d="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -28,6 +28,9 @@ declare(strict_types=1);
namespace OCA\Talk\Controller;
use InvalidArgumentException;
use OCA\Talk\Exceptions\CannotReachRemoteException;
use OCA\Talk\Exceptions\RemoteClientException;
use OCA\Talk\Middleware\Attribute\FederationSupported;
use OCA\Talk\Middleware\Attribute\RequireModeratorParticipant;
use OCA\Talk\Middleware\Attribute\RequireParticipantOrLoggedInAndListedConversation;
use OCA\Talk\ResponseDefinitions;
@ -38,7 +41,6 @@ use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\AppFramework\Http\Response;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserSession;
@ -132,10 +134,20 @@ class AvatarController extends AEnvironmentAwareController {
*
* 200: Room avatar returned
*/
#[FederationSupported]
#[PublicPage]
#[NoCSRFRequired]
#[RequireParticipantOrLoggedInAndListedConversation]
public function getAvatar(bool $darkTheme = false): Response {
public function getAvatar(bool $darkTheme = false): FileDisplayResponse {
if ($this->room->getRemoteServer()) {
/** @var \OCA\Talk\Federation\Proxy\TalkV1\Controller\AvatarController $proxy */
$proxy = \OCP\Server::get(\OCA\Talk\Federation\Proxy\TalkV1\Controller\AvatarController::class);
try {
return $proxy->getAvatar($this->room, $this->participant, $darkTheme);
} catch (RemoteClientException|CannotReachRemoteException) {
// Falling back to a local "globe" avatar for indicating the federation
}
}
$file = $this->avatarService->getAvatar($this->getRoom(), $this->userSession->getUser(), $darkTheme);
$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => $file->getMimeType()]);
@ -151,6 +163,7 @@ class AvatarController extends AEnvironmentAwareController {
*
* 200: Room avatar returned
*/
#[FederationSupported]
#[PublicPage]
#[NoCSRFRequired]
#[RequireParticipantOrLoggedInAndListedConversation]

View file

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2024 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Talk\Federation\Proxy\TalkV1\Controller;
use OCA\Talk\Exceptions\CannotReachRemoteException;
use OCA\Talk\Exceptions\RemoteClientException;
use OCA\Talk\Federation\Proxy\TalkV1\ProxyRequest;
use OCA\Talk\Participant;
use OCA\Talk\ResponseDefinitions;
use OCA\Talk\Room;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\Files\SimpleFS\InMemoryFile;
/**
* @psalm-import-type TalkChatMentionSuggestion from ResponseDefinitions
* @psalm-import-type TalkChatMessageWithParent from ResponseDefinitions
*/
class AvatarController {
public function __construct(
protected ProxyRequest $proxy,
) {
}
/**
* @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>
*
* 200: Room avatar returned
* @throws RemoteClientException
* @throws CannotReachRemoteException
*/
public function getAvatar(Room $room, Participant $participant, bool $darkTheme): FileDisplayResponse {
$proxy = $this->proxy->get(
$participant->getAttendee()->getInvitedCloudId(),
$participant->getAttendee()->getAccessToken(),
$room->getRemoteServer() . '/ocs/v2.php/apps/spreed/api/v1/room/' . $room->getRemoteToken() . '/avatar' . ($darkTheme ? '/dark' : ''),
);
$content = $proxy->getBody();
if ($content === '') {
throw new CannotReachRemoteException('No avatar content received');
}
$file = new InMemoryFile($room->getToken(), $content);
$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => $file->getMimeType()]);
// Cache for 1 day
$response->cacheFor(60 * 60 * 24, false, true);
return $response;
}
}

View file

@ -304,6 +304,9 @@ class AvatarService {
if ($room->getObjectType() === Room::OBJECT_TYPE_PHONE) {
return __DIR__ . '/../../img/icon-conversation-phone-' . $colorTone . '.svg';
}
if ($room->getRemoteServer() !== '') {
return __DIR__ . '/../../img/icon-conversation-federation-' . $colorTone . '.svg';
}
if ($room->getType() === Room::TYPE_PUBLIC) {
return __DIR__ . '/../../img/icon-conversation-public-' . $colorTone . '.svg';
}