Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement dashboard IAPIWidget #7942

Merged
merged 6 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .drone.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ local PipelinePostgreSQL(test_set) = Pipeline(
PipelineSQLite("conversation"),
PipelineSQLite("conversation-2"),
PipelineSQLite("federation"),
PipelineSQLite("integration"),
PipelineSQLite("reaction"),
PipelineSQLite("sharing"),
PipelineSQLite("sharing-2"),
Expand All @@ -135,6 +136,7 @@ local PipelinePostgreSQL(test_set) = Pipeline(
PipelineMySQL("conversation"),
PipelineMySQL("conversation-2"),
PipelineMySQL("federation"),
PipelineMySQL("integration"),
PipelineMySQL("reaction"),
PipelineMySQL("sharing"),
PipelineMySQL("sharing-2"),
Expand All @@ -145,6 +147,7 @@ local PipelinePostgreSQL(test_set) = Pipeline(
PipelinePostgreSQL("conversation"),
PipelinePostgreSQL("conversation-2"),
PipelinePostgreSQL("federation"),
PipelinePostgreSQL("integration"),
PipelinePostgreSQL("reaction"),
PipelinePostgreSQL("sharing"),
PipelinePostgreSQL("sharing-2"),
Expand Down
132 changes: 132 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,42 @@ trigger:
- push
---
kind: pipeline
name: int-sqlite-integration
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
name: cache
steps:
- commands:
- bash tests/drone-run-integration-tests.sh || exit 0
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST
- cd ../server
- ./occ app:enable $APP_NAME
- git clone --depth 1 -b $NOTIFICATIONS_BRANCH https:/nextcloud/notifications
apps/notifications
- ./occ app:enable notifications
- cd apps/$APP_NAME
- composer --version
- composer self-update --2
- composer install
- cd tests/integration/
- bash run.sh features/integration
environment:
APP_NAME: spreed
CORE_BRANCH: master
DATABASEHOST: sqlite
GUESTS_BRANCH: master
NOTIFICATIONS_BRANCH: master
image: ghcr.io/nextcloud/continuous-integration-php8.0:latest
name: integration-integration
trigger:
branch:
- master
- stable*
event:
- push
---
kind: pipeline
name: int-sqlite-reaction
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
Expand Down Expand Up @@ -634,6 +670,57 @@ trigger:
- push
---
kind: pipeline
name: int-mysql-integration
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
name: cache
- command:
- --innodb_large_prefix=true
- --innodb_file_format=barracuda
- --innodb_file_per_table=true
- --sql-mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
environment:
MYSQL_DATABASE: oc_autotest
MYSQL_PASSWORD: owncloud
MYSQL_ROOT_PASSWORD: owncloud
MYSQL_USER: oc_autotest
image: ghcr.io/nextcloud/continuous-integration-mariadb-10.4:10.4
name: mysql
tmpfs:
- /var/lib/mysql
steps:
- commands:
- bash tests/drone-run-integration-tests.sh || exit 0
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST
- cd ../server
- ./occ app:enable $APP_NAME
- git clone --depth 1 -b $NOTIFICATIONS_BRANCH https:/nextcloud/notifications
apps/notifications
- ./occ app:enable notifications
- cd apps/$APP_NAME
- composer --version
- composer self-update --2
- composer install
- cd tests/integration/
- bash run.sh features/integration
environment:
APP_NAME: spreed
CORE_BRANCH: master
DATABASEHOST: mysql
GUESTS_BRANCH: master
NOTIFICATIONS_BRANCH: master
image: ghcr.io/nextcloud/continuous-integration-php8.0:latest
name: integration-integration
trigger:
branch:
- master
- stable*
event:
- pull_request
- push
---
kind: pipeline
name: int-mysql-reaction
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
Expand Down Expand Up @@ -1059,6 +1146,51 @@ trigger:
- push
---
kind: pipeline
name: int-pgsql-integration
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
name: cache
- environment:
POSTGRES_DB: oc_autotest_dummy
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PASSWORD: ""
POSTGRES_USER: oc_autotest
image: ghcr.io/nextcloud/continuous-integration-postgres-13:postgres-13
name: pgsql
tmpfs:
- /var/lib/postgresql/data
steps:
- commands:
- bash tests/drone-run-integration-tests.sh || exit 0
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST
- cd ../server
- ./occ app:enable $APP_NAME
- git clone --depth 1 -b $NOTIFICATIONS_BRANCH https:/nextcloud/notifications
apps/notifications
- ./occ app:enable notifications
- cd apps/$APP_NAME
- composer --version
- composer self-update --2
- composer install
- cd tests/integration/
- bash run.sh features/integration
environment:
APP_NAME: spreed
CORE_BRANCH: master
DATABASEHOST: pgsql
GUESTS_BRANCH: master
NOTIFICATIONS_BRANCH: master
image: ghcr.io/nextcloud/continuous-integration-php8.0:latest
name: integration-integration
trigger:
branch:
- master
- stable*
event:
- push
---
kind: pipeline
name: int-pgsql-reaction
services:
- image: ghcr.io/nextcloud/continuous-integration-redis:latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
/tests/php/.phpunit.result.cache
/tests/integration/vendor
/tests/integration/output
/drone

# Compiled javascript
/js
Expand Down
131 changes: 128 additions & 3 deletions lib/Dashboard/TalkWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,37 @@

namespace OCA\Talk\Dashboard;

use OCP\Dashboard\IWidget;
use OCA\Talk\Chat\MessageParser;
use OCA\Talk\Manager;
use OCA\Talk\Room;
use OCP\Comments\IComment;
use OCP\Dashboard\IAPIWidget;
use OCP\Dashboard\IButtonWidget;
use OCP\Dashboard\IIconWidget;
use OCP\Dashboard\IOptionWidget;
use OCP\Dashboard\Model\WidgetButton;
use OCP\Dashboard\Model\WidgetItem;
use OCP\Dashboard\Model\WidgetOptions;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Util;

class TalkWidget implements IWidget {
class TalkWidget implements IAPIWidget, IIconWidget, IButtonWidget, IOptionWidget {
private IURLGenerator $url;
private IL10N $l10n;
private Manager $manager;
private MessageParser $messageParser;

public function __construct(
IURLGenerator $url,
IL10N $l10n
IL10N $l10n,
Manager $manager,
MessageParser $messageParser
) {
$this->url = $url;
$this->l10n = $l10n;
$this->manager = $manager;
$this->messageParser = $messageParser;
}

/**
Expand Down Expand Up @@ -70,6 +86,30 @@ public function getIconClass(): string {
return 'dashboard-talk-icon';
}

public function getWidgetOptions(): WidgetOptions {
return new WidgetOptions(true);
}

/**
* @return \OCP\Dashboard\Model\WidgetButton[]
*/
public function getWidgetButtons(string $userId): array {
$buttons = [];
$buttons[] = new WidgetButton(
WidgetButton::TYPE_MORE,
$this->url->linkToRouteAbsolute('spreed.Page.index'),
$this->l10n->t('More unread mentions')
);
return $buttons;
}

/**
* @inheritDoc
*/
public function getIconUrl(): string {
return $this->url->getAbsoluteURL($this->url->imagePath('spreed', 'app-dark.svg'));
}

/**
* @inheritDoc
*/
Expand All @@ -84,4 +124,89 @@ public function load(): void {
Util::addStyle('spreed', 'icons');
Util::addScript('spreed', 'talk-dashboard');
}

public function getItems(string $userId, ?string $since = null, int $limit = 7): array {
$rooms = $this->manager->getRoomsForUser($userId, [], true);

$rooms = array_filter($rooms, static function (Room $room) use ($userId) {
$participant = $room->getParticipant($userId);
$attendee = $participant->getAttendee();
return $room->getLastMessage() && $room->getLastMessage()->getId() > $attendee->getLastReadMessage();
});

uasort($rooms, [$this, 'sortRooms']);

$rooms = array_slice($rooms, 0, $limit);

$result = [];
foreach ($rooms as $room) {
$result[] = $this->prepareRoom($room, $userId);
}

return $result;
}

protected function prepareRoom(Room $room, string $userId): WidgetItem {
$participant = $room->getParticipant($userId);
$subtitle = '';

$lastMessage = $room->getLastMessage();
if ($lastMessage instanceof IComment) {
$message = $this->messageParser->createMessage($room, $participant, $room->getLastMessage(), $this->l10n);
$this->messageParser->parseMessage($message);
if ($message->getVisibility()) {
$placeholders = $replacements = [];

foreach ($message->getMessageParameters() as $placeholder => $parameter) {
$placeholders[] = '{' . $placeholder . '}';
if ($parameter['type'] === 'user' || $parameter['type'] === 'guest') {
$replacements[] = '@' . $parameter['name'];
} else {
$replacements[] = $parameter['name'];
}
}

$subtitle = str_replace($placeholders, $replacements, $message->getMessage());
}
}

return new WidgetItem(
$room->getDisplayName($userId),
$subtitle,
$this->url->linkToRouteAbsolute('spreed.Page.showCall', ['token' => $room->getToken()]),
$this->getRoomIconUrl($room, $userId)
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Items itself don't have the options and the widget itself already has the "roundIcon" option set.
https:/nextcloud/spreed/pull/7942/files#diff-9d0ac71d126947c6f952b00aba3afc1df1e75b99431cb53086b0c43c2f677c29R90

}

protected function getRoomIconUrl(Room $room, string $userId): string {
if ($room->getType() === Room::TYPE_ONE_TO_ONE) {
$participants = json_decode($room->getName(), true);

foreach ($participants as $p) {
if ($p !== $userId) {
return $this->url->linkToRouteAbsolute(
'core.avatar.getAvatar',
[
'userId' => $p,
'size' => 64,
]
);
}
}
} elseif ($room->getObjectType() === 'file') {
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'filetypes/file.svg'));
} elseif ($room->getObjectType() === 'share:password') {
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/password.svg'));
} elseif ($room->getObjectType() === 'emails') {
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/mail.svg'));
} elseif ($room->getType() === Room::TYPE_PUBLIC) {
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/public.svg'));
}

return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/group.svg'));
}

protected function sortRooms(Room $roomA, Room $roomB): int {
return $roomA->getLastActivity() < $roomB->getLastActivity() ? -1 : 1;
}
}
Loading