feat: Add Search Provider

pull/224/head
Brtbr 2022-10-16 14:11:28 +02:00
parent b435d4b9f7
commit c80135c4ce
6 changed files with 211 additions and 7 deletions

View File

@ -1,5 +0,0 @@
<?php
OCP\Util::addScript('bbb', 'filelist');
\OC::$server->query(\OCA\BigBlueButton\AppInfo\Application::class);

72
img/app-grey.svg Normal file
View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="32"
width="32"
version="1.0"
viewBox="0 0 32 32"
id="svg4"
sodipodi:docname="app-grey.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1479"
inkscape:window-height="997"
id="namedview6"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="13.46269"
inkscape:cy="7.070207"
inkscape:window-x="2110"
inkscape:window-y="585"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
style="color:#969696;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#969696;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.48244119;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 6.140625,2 C 3.8448872,2 2,3.9362265 2,6.2421875 V 25.757812 C 2,28.063773 3.8448872,30 6.140625,30 h 19.71875 C 28.155113,30 30,28.063773 30,25.757812 V 6.2421875 C 30,3.9362265 28.155113,2 25.859375,2 Z m 0,2.4824219 h 19.71875 c 0.917462,0 1.658203,0.7417266 1.658203,1.7597656 V 25.757812 c 0,1.01804 -0.740741,1.759766 -1.658203,1.759766 H 6.140625 c -0.9174623,0 -1.6582031,-0.741726 -1.6582031,-1.759766 V 6.2421875 c 0,-1.018039 0.7407408,-1.7597656 1.6582031,-1.7597656 z"
id="rect817"
inkscape:connector-curvature="0" />
<g
id="g891"
transform="matrix(0.72859037,0,0,0.72859037,4.3425539,7.2153805)"
style="fill:#969696">
<path
id="path819"
d="m 16,16.40625 a 9.4915257,9.4915257 0 0 0 -9.4921875,9.492188 9.4915257,9.4915257 0 0 0 0.3574219,2.576171 H 25.126953 A 9.4915257,9.4915257 0 0 0 25.492188,25.898438 9.4915257,9.4915257 0 0 0 16,16.40625 Z"
style="opacity:1;fill:#969696;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.37037015;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
inkscape:connector-curvature="0" />
<circle
r="6.2372885"
cy="12.338983"
cx="16"
id="path819-1"
style="opacity:1;fill:#969696;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.21481466;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -15,19 +15,25 @@ use \OCA\BigBlueButton\Event\RoomShareDeletedEvent;
use \OCA\BigBlueButton\Listener\UserDeletedListener; use \OCA\BigBlueButton\Listener\UserDeletedListener;
use \OCA\BigBlueButton\Middleware\HookMiddleware; use \OCA\BigBlueButton\Middleware\HookMiddleware;
use \OCA\BigBlueButton\Middleware\JoinMiddleware; use \OCA\BigBlueButton\Middleware\JoinMiddleware;
use \OCA\BigBlueButton\Search\Provider;
use \OCP\AppFramework\App; use \OCP\AppFramework\App;
use \OCP\AppFramework\QueryException; use \OCP\AppFramework\QueryException;
use \OCP\AppFramework\Bootstrap\IBootContext;
use \OCP\AppFramework\Bootstrap\IBootstrap;
use \OCP\AppFramework\Bootstrap\IRegistrationContext;
use \OCP\EventDispatcher\IEventDispatcher; use \OCP\EventDispatcher\IEventDispatcher;
use \OCP\IConfig; use \OCP\IConfig;
use \OCP\Settings\IManager as ISettingsManager; use \OCP\Settings\IManager as ISettingsManager;
use \OCP\User\Events\UserDeletedEvent; use \OCP\User\Events\UserDeletedEvent;
use \OCP\Util;
if ((@include_once __DIR__ . '/../../vendor/autoload.php') === false) { if ((@include_once __DIR__ . '/../../vendor/autoload.php') === false) {
throw new \Exception('Cannot include autoload. Did you run install dependencies using composer?'); throw new \Exception('Cannot include autoload. Did you run install dependencies using composer?');
} }
class Application extends App { class Application extends App implements IBootstrap {
public const ID = 'bbb'; public const ID = 'bbb';
public const ORDER = 80;
public function __construct(array $urlParams = []) { public function __construct(array $urlParams = []) {
parent::__construct(self::ID, $urlParams); parent::__construct(self::ID, $urlParams);
@ -50,6 +56,14 @@ class Application extends App {
} else { } else {
$this->registerAsPersonalSetting(); $this->registerAsPersonalSetting();
} }
Util::addScript('bbb', 'filelist');
}
public function boot(IBootContext $context): void {}
public function register(IRegistrationContext $context): void {
$context->registerSearchProvider(Provider::class);
} }
private function registerAsPersonalSetting(): void { private function registerAsPersonalSetting(): void {
@ -77,7 +91,7 @@ class Application extends App {
$server->getNavigationManager()->add(function () use ($server, $name) { $server->getNavigationManager()->add(function () use ($server, $name) {
return [ return [
'id' => self::ID, 'id' => self::ID,
'order' => 80, 'order' => self::ORDER,
'href' => $server->getURLGenerator()->linkToRoute('bbb.page.index'), 'href' => $server->getURLGenerator()->linkToRoute('bbb.page.index'),
'icon' => $server->getURLGenerator()->imagePath('bbb', 'app.svg'), 'icon' => $server->getURLGenerator()->imagePath('bbb', 'app.svg'),
'name' => $name, 'name' => $name,

View File

@ -99,4 +99,21 @@ class RoomMapper extends QBMapper {
/** @var array<Room> */ /** @var array<Room> */
return $this->findEntities($qb); return $this->findEntities($qb);
} }
/**
* @return array<Room>
*/
public function search(string $userId, string $query): array {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->tableName, 'r')
->where($qb->expr()->eq('r.user_id', $qb->createNamedParameter($userId)))
->andwhere($qb->expr()->ILike('name',
$qb->createNamedParameter('%' . $this->db->escapeLikeParameter($query) . '%', IQueryBuilder::PARAM_STR),
IQueryBuilder::PARAM_STR));
/** @var array<Room> */
return $this->findEntities($qb);
}
} }

97
lib/Search/Provider.php Normal file
View File

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace OCA\BigBlueButton\Search;
use OCA\BigBlueButton\AppInfo\Application;
use OCA\BigBlueButton\Service\RoomService;
use OCA\BigBlueButton\Db\Room;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Search\IProvider;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;
use function array_map;
class Provider implements IProvider {
/** @var RoomService */
private $service;
/** @var IL10N */
private $l10n;
/** @var IURLGenerator */
private $urlGenerator;
public function __construct(RoomService $service, IL10N $l10n, IURLGenerator $urlGenerator) {
$this->service = $service;
$this->l10n = $l10n;
$this->urlGenerator = $urlGenerator;
}
public function getId(): string {
return Application::ID;
}
public function getName(): string {
return 'BBB';
}
public function getOrder(string $route, array $routeParameters): int {
if (strpos($route, Application::ID . '.') === 0) {
return -1;
}
return Application::ORDER;
}
private function getAccess(string $access): string {
switch ($access) {
case 'public':
$translatedAccess = $this->l10n->t('Public');
break;
case 'password':
$translatedAccess = $this->l10n->t('Internal + Password protection for guests');
break;
case 'waiting_room':
$translatedAccess = $this->l10n->t('Internal + Waiting room for guests');
break;
case 'waiting_room_all':
$translatedAccess = $this->l10n->t('Waiting room for all users');
break;
case 'internal':
$translatedAccess = $this->l10n->t('Internal');
break;
case 'internal_restricted':
$translatedAccess = $this->l10n->t('Internal restricted');
break;
}
return $translatedAccess;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
$rooms = $this->service->search(
$user,
$query
);
$results = array_map(function(Room $room) {
return [
new SearchResultEntry(
'',
$room->getName(),
$this->getAccess($room->getAccess()),
$this->urlGenerator->linkToRoute('bbb.page.index'),
$this->urlGenerator->imagePath('bbb', 'app-grey.svg')
)
];
}, $rooms);
return SearchResult::complete(
'BBB',
$results
);
}
}

View File

@ -13,7 +13,9 @@ use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig; use OCP\IConfig;
use OCP\IUser;
use OCP\Security\ISecureRandom; use OCP\Security\ISecureRandom;
use OCP\Search\ISearchQuery;
class RoomService { class RoomService {
@ -85,6 +87,13 @@ class RoomService {
return $this->mapper->findByUserId($userId); return $this->mapper->findByUserId($userId);
} }
/**
* @return array<Room>
*/
public function search(IUser $userId, ISearchQuery $query): array {
return $this->mapper->search($userId->getUID(), $query->getTerm());
}
public function create(string $name, string $welcome, int $maxParticipants, bool $record, string $access, string $userId): \OCP\AppFramework\Db\Entity { public function create(string $name, string $welcome, int $maxParticipants, bool $record, string $access, string $userId): \OCP\AppFramework\Db\Entity {
$room = new Room(); $room = new Room();