Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • petre/nextcloud-app-podcast
  • onny/nextcloud-app-podcast
2 results
Show changes
Showing
with 9399 additions and 1076 deletions
......@@ -25,14 +25,25 @@ namespace OCA\Podcast\Controller;
use OCA\Podcast\AppInfo\Application;
use OCA\Podcast\Service\EpisodeService;
use OCA\Podcast\Service\FyydApiService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
use OCP\ILogger;
use OCP\Http\Client\IClientService;
class EpisodeController extends Controller {
/** @var ILogger */
private $logger;
/** @var EpisodesService */
private $service;
/** @var FyydApiService */
private $fyydapi;
/** @var string */
private $userId;
......@@ -40,17 +51,69 @@ class EpisodeController extends Controller {
public function __construct(IRequest $request,
EpisodeService $service,
FyydApiService $fyydapi,
ILogger $logger,
$userId) {
parent::__construct(Application::APP_ID, $request);
$this->service = $service;
$this->fyydapi = $fyydapi;
$this->logger = $logger;
$this->userId = $userId;
}
/**
* @NoAdminRequired
*/
public function index(): DataResponse {
return new DataResponse($this->service->findAll($this->userId));
public function index(int $episode_id = null, int $podcast_id = null,
int $count = 20, int $page = 0, string $sortBy = null): DataResponse {
$data = $this->service->findAll($this->userId, $sortBy);
if ($episode_id) {
$list = $this->fyydapi->queryEpisode($episode_id);
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $list['data']['id']) {
$list['data']['lastplayed'] = $localEpisode->getLastplayed();
$list['data']['playtime'] = $localEpisode->getPlaytime();
}
}
return new DataResponse($list);
} else if ($podcast_id) {
$list = $this->fyydapi->queryEpisodes($podcast_id, $count, $page);
foreach($list['data']['episodes'] as $key=>$fyydEpisode) {
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $fyydEpisode['id']) {
$list['data']['episodes'][$key]['lastplayed'] = $localEpisode->getLastplayed();
$list['data']['episodes'][$key]['playtime'] = $localEpisode->getPlaytime();
}
}
}
return new DataResponse($list);
}
$data = array_slice($data, $page * $count, $count);
if (count($data) === $count) {
$nextPage = $page + 1;
} else {
$nextPage = null;
};
$response = [
"meta" => [
"paging" => [
"next_page" => $nextPage,
],
],
"data" => [
"episodes" => $data,
],
];
return new DataResponse($response);
}
/**
......@@ -65,27 +128,27 @@ class EpisodeController extends Controller {
/**
* @NoAdminRequired
*/
public function create(int $id, string $imgurl, string $title,
public function create(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcastid
string $enclosure, string $description, int $podcast_id
): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $title,
return new DataResponse($this->service->create($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$podcastid, $this->userId));
$podcast_id, $this->userId));
}
/**
* @NoAdminRequired
*/
public function update(int $id, string $imgurl, string $title,
public function update(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcastid
string $enclosure, string $description, int $podcast_id
): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $title,
return $this->handleNotFound(function () use ($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$podcastid) {
return $this->service->update($id, $imgurl, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $description, $podcastid,
$podcast_id) {
return $this->service->update($id, $imgURL, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $description, $podcast_id,
$this->userId);
});
}
......
<?php
/**
* Podcast App
*
* @author Jonas Heinrich
* @copyright 2021 Jonas Heinrich <onny@project-insanity.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Podcast\Controller;
use OC;
use OCA\Podcast\ExportResponse;
use OCA\Podcast\AppInfo\Application;
use OCA\Podcast\Service\ShowService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
use SimpleXMLElement;
use DOMDocument;
class ExportController extends Controller {
/** @var ShowService */
private $service;
/** @var string */
private $userId;
use Errors;
public function __construct(IRequest $request,
ShowService $service,
$userId) {
parent::__construct(Application::APP_ID, $request);
$this->service = $service;
$this->userId = $userId;
}
/**
* @NoAdminRequired
*/
public function index() {
$xml = new SimpleXMLElement('<?xml version="1.0"?><opml version="1.0"></opml>');
$trackList = $xml->addChild('body');
foreach($this->service->findAll($this->userId) as $show) {
$track = $trackList->addChild('outline');
$track->addAttribute('type', 'rss');
$track->addAttribute('text', $show->getTitle());
$track->addAttribute('title', $show->getTitle());
$track->addAttribute('xmlUrl', $show->getFeedurl());
$track->addAttribute('htmlUrl', $show->getHomepage());
}
$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
return new ExportResponse($dom->saveXML());
}
}
......@@ -25,6 +25,7 @@ namespace OCA\Podcast\Controller;
use OCA\Podcast\AppInfo\Application;
use OCA\Podcast\Service\ShowService;
use OCA\Podcast\Service\FyydApiService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
......@@ -33,6 +34,9 @@ class ShowController extends Controller {
/** @var ShowsService */
private $service;
/** @var FyydApiService */
private $fyydapi;
/** @var string */
private $userId;
......@@ -40,17 +44,55 @@ class ShowController extends Controller {
public function __construct(IRequest $request,
ShowService $service,
FyydApiService $fyydapi,
$userId) {
parent::__construct(Application::APP_ID, $request);
$this->service = $service;
$this->fyydapi = $fyydapi;
$this->userId = $userId;
}
/**
* @NoAdminRequired
*/
public function index(): DataResponse {
return new DataResponse($this->service->findAll($this->userId));
public function index(int $podcast_id = null, string $category = null,
int $count = 20, int $page = 0): DataResponse {
$data = $this->service->findAll($this->userId);
if ($category) {
$list = $this->fyydapi->queryCategory($category, $count, $page);
return new DataResponse($list);
} else if ($podcast_id) {
$list = $this->fyydapi->queryPodcast($podcast_id);
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $list['data']['id']) {
$list['data']['dateadded'] = intval($localEpisode->getDateadded());
}
}
return new DataResponse($list);
}
$data = array_slice($data, $page * $count, $count);
if (count($data) === $count) {
$nextPage = $page + 1;
} else {
$nextPage = null;
};
$response = [
"meta" => [
"paging" => [
"next_page" => $nextPage,
],
],
"data" => $data,
];
return new DataResponse($response);
}
/**
......@@ -65,21 +107,23 @@ class ShowController extends Controller {
/**
* @NoAdminRequired
*/
public function create(int $id, string $imgurl, string $author,
string $title, string $lastpub, int $dateadded): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $author,
$title, $lastpub, $dateadded, $this->userId));
public function create(int $id, string $smallImageURL, string $author,
string $title, string $lastpub, int $dateadded, string $homepage,
string $feedurl): DataResponse {
return new DataResponse($this->service->create($id, $smallImageURL, $author,
$title, $lastpub, $dateadded, $homepage, $feedurl, $this->userId));
}
/**
* @NoAdminRequired
*/
public function update(int $id, string $imgurl, string $author,
string $title, string $lastpub, int $dateadded): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $author,
$title, $lastpub, $dateadded) {
return $this->service->update($id, $imgurl, $author, $title, $lastpub,
$dateadded, $this->userId);
public function update(int $id, string $smallImageURL, string $author,
string $title, string $lastpub, int $dateadded, string $homepage,
string $feedurl): DataResponse {
return $this->handleNotFound(function () use ($id, $smallImageURL, $author,
$title, $lastpub, $dateadded, $homepage, $feedurl) {
return $this->service->update($id, $smallImageURL, $author, $title, $lastpub,
$dateadded, $homepage, $feedurl, $this->userId);
});
}
......
......@@ -42,7 +42,7 @@ class Episode extends Entity implements JsonSerializable {
public function jsonSerialize(): array {
return [
'id' => $this->id,
'imgurl' => $this->imgurl,
'imgURL' => $this->imgurl,
'title' => $this->title,
'pubdate' => $this->pubdate,
'duration' => $this->duration,
......@@ -50,7 +50,7 @@ class Episode extends Entity implements JsonSerializable {
'lastplayed' => $this->lastplayed,
'enclosure' => $this->enclosure,
'description' => $this->description,
'podcastid' => $this->podcastid,
'podcast_id' => $this->podcastid,
];
}
}
......@@ -55,13 +55,29 @@ class EpisodeMapper extends QBMapper {
* @param string $userId
* @return array
*/
public function findAll(string $userId): array {
public function findAll(string $userId, string $sortBy = null): array {
if ($sortBy) {
if ($sortBy === 'pubdate') {
$sortBy = 'pubdate';
} else {
$sortBy = 'lastplayed';
}
} else {
$sortBy = 'lastplayed';
};
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from('episodes')
->orderBy('lastplayed', 'DESC')
->orderBy($sortBy, 'DESC')
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
/* For listening view, query only episodes which were already
listened */
if ($sortBy === 'lastplayed') {
$qb->andWhere($qb->expr()->gt('playtime',$qb->createNamedParameter(0)));
};
return $this->findEntities($qb);
}
}
......@@ -33,16 +33,20 @@ class Show extends Entity implements JsonSerializable {
protected $title;
protected $lastpub;
protected $dateadded;
protected $homepage;
protected $feedurl;
protected $userId;
public function jsonSerialize(): array {
return [
'id' => $this->id,
'imgurl' => $this->imgurl,
'smallImageURL' => $this->imgurl,
'author' => $this->author,
'title' => $this->title,
'lastpub' => $this->lastpub,
'dateadded' => $this->dateadded,
'homepage' => $this->homepage,
'feedurl' => $this->feedurl,
];
}
}
......@@ -61,7 +61,7 @@ class ShowMapper extends QBMapper {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from('shows')
->orderBy('dateadded', 'DESC')
->orderBy('lastpub', 'DESC')
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
return $this->findEntities($qb);
}
......
<?php
/**
* Podcast App
*
* @author Jonas Heinrich
* @copyright 2021 Jonas Heinrich <onny@project-insanity.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Podcast;
use OC;
use OC\HintException;
use OCP\AppFramework\Http\Response;
class ExportResponse extends Response {
private $returnstring;
public function __construct($returnstring) {
parent::__construct();
$user = OC::$server->getUserSession()->getUser();
if (is_null($user)) {
throw new HintException('User not logged in');
}
$userName = $user->getDisplayName();
$productName = OC::$server->getThemingDefaults()->getName();
$dateTime = OC::$server->getDateTimeFormatter();
$export_name = '"' . $productName . ' Podcast Subscriptions (' . $userName . ') (' . $dateTime->formatDate(time()) . ').opml"';
$this->addHeader("Cache-Control", "private");
$this->addHeader("Content-Type", " application/xml");
$this->addHeader("Content-Length", strlen($returnstring));
$this->addHeader("Content-Disposition", "attachment; filename=" . $export_name);
$this->returnstring = $returnstring;
}
public function render() {
return $this->returnstring;
}
}
......@@ -58,7 +58,7 @@ class Version000100Date20210201162900 extends SimpleMigrationStep {
$table->addColumn('lastpub', 'string', [
'notnull' => false,
]);
$table->addColumn('dateadded', 'integer', [
$table->addColumn('dateadded', 'bigint', [
'notnull' => false,
]);
......@@ -70,19 +70,16 @@ class Version000100Date20210201162900 extends SimpleMigrationStep {
'notnull' => true,
]);
if ($table->hasColumn('playtime')) {
$table->changeColumn('playtime', [
'type' => Type::getType('integer')
]);
$table->dropColumn('playtime');
$table->addColumn('playtime', 'integer');
};
if ($table->hasColumn('duration')) {
$table->changeColumn('duration', [
'type' => Type::getType('integer')
]);
$table->dropColumn('duration');
$table->addColumn('duration', 'integer');
};
if ($table->hasColumn('lastplayed')) {
$table->changeColumn('lastplayed', [
'type' => Type::getType('integer')
]);
$table->dropColumn('lastplayed');
$table->addColumn('lastplayed', 'bigint');
};
if ($table->hasColumn('author')) {
$table->dropColumn('author');
......
<?php
/**
* Podcast App
*
* @author Jonas Heinrich
* @copyright 2021 Jonas Heinrich <onny@project-insanity.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
*
*/
declare(strict_types=1);
namespace OCA\Podcast\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
use Doctrine\DBAL\Types\Type;
class Version000100Date20210315125200 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return void
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('shows');
$table->addColumn('homepage', 'string', [
'notnull' => false,
]);
$table->addColumn('feedurl', 'string', [
'notnull' => false,
]);
$table = $schema->getTable('episodes');
return $schema;
}
}
......@@ -40,8 +40,8 @@ class EpisodeService {
$this->mapper = $mapper;
}
public function findAll(string $userId): array {
return $this->mapper->findAll($userId);
public function findAll(string $userId, string $sortBy = null): array {
return $this->mapper->findAll($userId, $sortBy);
}
private function handleException(Exception $e): void {
......
<?php
/**
* Podcast App
*
* @author Jonas Heinrich
* @copyright 2021 Jonas Heinrich <onny@project-insanity.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
*
*/
declare(strict_types=1);
namespace OCA\Podcast\Service;
use OCP\IURLGenerator;
use OCP\Http\Client\IClientService;
use function urlencode;
class FyydApiService {
/** @var IClientService */
private $clientService;
/** @var IURLGenerator */
private $url;
public $baseUrl = "https://api.fyyd.de/0.2";
public function __construct(
IClientService $clientService,
IURLGenerator $url
) {
$this->clientService = $clientService;
$this->url = $url;
}
public function queryEpisodes(int $podcast_id, int $count = 20, int $page = 0) {
$url = $this->baseUrl . "/podcast/episodes";
$options['query'] = [
'podcast_id' => $podcast_id,
'count' => $count,
'page' => $page
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryEpisode(int $episode_id) {
$url = $this->baseUrl . "/episode";
$options['query'] = [
'episode_id' => $episode_id,
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryPodcast(int $podcast_id) {
$url = $this->baseUrl . "/podcast";
$options['query'] = [
'podcast_id' => $podcast_id,
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryCategory(string $category, int $count = 20,
int $page = 0) {
if ($category === 'hot') {
$url = $this->baseUrl . "/feature/podcast/hot";
$options['query'] = [
'count' => $count,
'page' => $page,
];
} else if ($category === 'latest') {
$url = $this->baseUrl . "/podcast/latest";
$options['query'] = [
'count' => $count,
'page' => $page,
];
} else {
$url = $this->baseUrl . "/category";
$options['query'] = [
'count' => $count,
'page' => $page,
'category_id' => $category,
];
}
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
}
......@@ -67,7 +67,7 @@ class ShowService {
}
public function create($id, $imgurl, $author, $title, $lastpub, $dateadded,
$userId) {
$homepage, $feedurl, $userId) {
$show = new Show();
$show->setId($id);
$show->setImgurl($imgurl);
......@@ -75,12 +75,14 @@ class ShowService {
$show->setTitle($title);
$show->setLastpub($lastpub);
$show->setDateadded($dateadded);
$show->setHomepage($homepage);
$show->setFeedurl($feedurl);
$show->setUserId($userId);
return $this->mapper->insert($show);
}
public function update($id, $imgurl, $author, $title, $lastpub, $dateadded,
$userId) {
$homepage, $feedurl, $userId) {
try {
$show = $this->mapper->find($id, $userId);
$show->setImgurl($imgurl);
......@@ -88,6 +90,8 @@ class ShowService {
$show->setTitle($title);
$show->setLastpub($lastpub);
$show->setDateadded($dateadded);
$show->setHomepage($homepage);
$show->setFeedurl($feedurl);
return $this->mapper->update($show);
} catch (Exception $e) {
$this->handleException($e);
......
This diff is collapsed.
{
"name": "podcast",
"description": "Listen to your favorite podcast shows in Nextcloud",
"version": "0.2.0",
"version": "0.4.0",
"author": "Jonas Heinrich <onny@project-insanity.org>",
"contributors": [
"Jonas Heinrich <onny@project-insanity.org>"
......@@ -30,24 +30,32 @@
"stylelint:fix": "stylelint src --fix"
},
"dependencies": {
"@nextcloud/axios": "^1.6.0",
"@nextcloud/dialogs": "^3.1.1",
"@babel/eslint-parser": "^7.15.8",
"@nextcloud/auth": "^1.3.0",
"@nextcloud/axios": "^1.7.0",
"@nextcloud/dialogs": "^3.1.2",
"@nextcloud/l10n": "^1.4.1",
"@nextcloud/moment": "^1.1.1",
"@nextcloud/router": "^1.2.0",
"@nextcloud/vue": "^2.9.0",
"@nextcloud/vue-dashboard": "^1.0.1",
"autoprefixer": "^9.8.6",
"howler": "^2.2.1",
"javascript-time-ago": "^2.3.4",
"music-metadata": "^7.6.6",
"postcss-loader": "^4.2.0",
"style-loader": "^2.0.0",
"vue": "^2.6.12",
"vue-content-loader": "^0.2.3",
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^4.2.0",
"@nextcloud/vue-dashboard": "^2.0.1",
"autoprefixer": "^10.3.7",
"eslint-plugin-jsdoc": "^36.1.1",
"eslint-webpack-plugin": "^3.0.1",
"howler": "^2.2.3",
"javascript-time-ago": "^2.3.9",
"linkify-string": "^3.0.3",
"music-metadata": "^7.11.4",
"node-polyfill-webpack-plugin": "^1.1.4",
"postcss-loader": "^6.2.0",
"splitpanes": "^2.3.8",
"style-loader": "^3.3.0",
"vue": "^2.6.14",
"vue-content-loader": "^2.0.0",
"vue-lazyload": "^1.3.3",
"vue-resize-observer": "^1.0.37",
"vue-router": "^3.5.1",
"vue-material-design-icons": "^4.13.0",
"vue-resize-directive": "^1.2.0",
"vue-router": "^3.5.2",
"vue-show-more-text": "^2.0.2",
"vuex": "^3.6.2"
},
......@@ -58,38 +66,35 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/core": "^7.15.8",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.12.11",
"@nextcloud/browserslist-config": "^1.0.0",
"@nextcloud/eslint-config": "^2.2.0",
"@nextcloud/eslint-plugin": "^1.5.0",
"@nextcloud/webpack-vue-config": "^1.4.1",
"@vue/test-utils": "^1.1.2",
"babel-eslint": "^10.1.0",
"@babel/preset-env": "^7.15.8",
"@nextcloud/browserslist-config": "^2.2.0",
"@nextcloud/eslint-config": "^6.1.0",
"@nextcloud/eslint-plugin": "^2.0.0",
"@nextcloud/webpack-vue-config": "^4.1.0",
"@vue/test-utils": "^1.2.2",
"babel-loader": "^8.2.2",
"css-loader": "^3.6.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.1",
"eslint-import-resolver-webpack": "^0.13.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-html": "^6.1.1",
"eslint-plugin-import": "^2.22.1",
"css-loader": "^6.4.0",
"eslint": "^8.0.1",
"eslint-config-standard": "^16.0.3",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^6.2.2",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.19.1",
"file-loader": "^6.2.0",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"stylelint": "^13.9.0",
"stylelint-config-recommended-scss": "^4.2.0",
"stylelint-scss": "^3.18.0",
"stylelint-webpack-plugin": "^2.1.1",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.12",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"webpack-merge": "^5.7.3"
"node-sass": "^6.0.1",
"sass-loader": "^12.2.0",
"stylelint": "^13.13.1",
"stylelint-config-recommended-scss": "^4.3.0",
"stylelint-scss": "^3.21.0",
"stylelint-webpack-plugin": "^3.0.1",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.58.2",
"webpack-cli": "^4.9.0",
"webpack-merge": "^5.8.0"
}
}
This diff is collapsed.
......@@ -27,6 +27,9 @@
<router-view />
</AppContent>
<Player />
<!-- <div class="floatControl">
Skip intro
</div> -->
</Content>
</template>
......@@ -45,7 +48,7 @@ export default {
Player,
},
created() {
this.$store.dispatch('loadShows')
this.$store.dispatch('loadVolume')
this.$store.dispatch('loadEpisodes')
},
}
......@@ -61,11 +64,33 @@ export default {
.app-content {
overflow: scroll;
height: calc(100vh - 78px);
height: calc(100vh - 98px);
}
.app-navigation {
bottom: 60px;
bottom: 80px;
}
.floatControl {
position: fixed;
bottom: 75px;
right: 25px;
height: 45px;
width: 120px;
background: rgba(66, 66, 66, 0.48);
z-index: 8001;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
border: 1px solid #464646;
cursor: pointer;
&:hover {
// background: rgba(161, 161, 161, 0.48);
background: rgba(66, 66, 66, 0.7);
}
}
</style>
......@@ -60,6 +60,7 @@ export default {
</script>
<style lang="scss">
.episodeContent {
.episodeContentHeader {
......@@ -68,24 +69,31 @@ export default {
padding: 10px 30px;
z-index: 60;
position: sticky;
top: 50px;
top: 0px;
background: white;
display: flex;
align-items: center;
margin-bottom: -1px;
}
h2 {
flex-grow: 1;
margin-bottom: 0px;
}
.menuToggle {
color: #1976d2;
cursor: pointer;
}
.boxContent {
a {
color: #1976d2;
}
}
}
</style>
......@@ -42,10 +42,9 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import { DashboardWidget } from '@nextcloud/vue-dashboard'
import { getRequestToken } from '@nextcloud/auth'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
const requesttoken = axios.defaults.headers.requesttoken
export default {
name: 'Dashboard',
......@@ -100,7 +99,7 @@ export default {
methods: {
fetchNotifications() {
const req = {}
axios.defaults.headers.requesttoken = requesttoken
axios.defaults.headers.requesttoken = getRequestToken()
axios.get(generateUrl('/apps/podcast/api/favorites'), req).then((response) => {
this.processNotifications(response.data)
this.state = 'ok'
......
<!--
- @copyright Copyright (c) 2021 Jonas Heinrich
-
- @author Jonas Heinrich <onny@project-insanity.org>
-
- @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/>.
-
-->
<template>
<div class="podcastSectionHeader">
<h1>{{ title }}</h1>
<slot />
</div>
</template>
<script>
export default {
name: 'Header',
props: {
title: {
type: String,
default: '',
},
},
}
</script>
<style lang="scss">
.podcastSectionHeader {
padding: 0px 20px 0px 65px;
display: flex;
align-items: center;
background-image: var(--icon-podcast-header-000);
background-repeat: no-repeat;
background-position: 30px 50%;
h1 {
flex-grow: 1;
font-size: 1.6em;
margin: 25px 0px 25px 0px;
}
a {
color: #1976d2;
cursor: pointer;
}
}
</style>