Fix actions
All checks were successful
repod / nextcloud (push) Successful in 50s
repod / nodejs (push) Successful in 1m23s

This commit is contained in:
Michel Roux 2023-08-29 08:48:54 +02:00
parent 7a08a0dc58
commit 5683d353bb
6 changed files with 43 additions and 39 deletions

View File

@ -13,7 +13,8 @@ declare(strict_types=1);
return [ return [
'routes' => [ 'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'episodes#index', 'url' => '/episodes', 'verb' => 'GET'], ['name' => 'episodes#action', 'url' => '/episodes/action', 'verb' => 'GET'],
['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'],
['name' => 'podcast#index', 'url' => '/podcast', 'verb' => 'GET'], ['name' => 'podcast#index', 'url' => '/podcast', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'], ['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'],
['name' => 'toplist#index', 'url' => '/toplist', 'verb' => 'GET'], ['name' => 'toplist#index', 'url' => '/toplist', 'verb' => 'GET'],

View File

@ -4,9 +4,12 @@ declare(strict_types=1);
namespace OCA\RePod\Controller; namespace OCA\RePod\Controller;
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
use OCA\RePod\AppInfo\Application; use OCA\RePod\AppInfo\Application;
use OCA\RePod\Core\EpisodeAction\EpisodeActionReader; use OCA\RePod\Core\EpisodeAction\EpisodeActionReader;
use OCA\RePod\Service\UserService;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\Http\Client\IClientService; use OCP\Http\Client\IClientService;
use OCP\IRequest; use OCP\IRequest;
@ -16,16 +19,29 @@ class EpisodesController extends Controller
public function __construct( public function __construct(
IRequest $request, IRequest $request,
private IClientService $clientService, private IClientService $clientService,
private EpisodeActionReader $episodeActionReader private EpisodeActionReader $episodeActionReader,
private EpisodeActionRepository $episodeActionRepository,
private UserService $userService
) { ) {
parent::__construct(Application::APP_ID, $request); parent::__construct(Application::APP_ID, $request);
} }
public function index(string $url): JSONResponse public function list(string $url): JSONResponse
{ {
$client = $this->clientService->newClient(); $client = $this->clientService->newClient();
$feed = $client->get($url); $feed = $client->get($url);
return new JSONResponse($this->episodeActionReader->parseRssXml((string) $feed->getBody()), $feed->getStatusCode()); return new JSONResponse($this->episodeActionReader->parseRssXml((string) $feed->getBody()), $feed->getStatusCode());
} }
public function action(string $url): JSONResponse
{
$action = $this->episodeActionRepository->findByEpisodeUrl($url, $this->userService->getUserUID());
if ($action) {
return new JSONResponse($action->toArray());
}
return new JSONResponse([], Http::STATUS_NOT_FOUND);
}
} }

View File

@ -22,8 +22,7 @@ use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;
* episodeGuid: string, * episodeGuid: string,
* episodePubDate: ?\DateTime, * episodePubDate: ?\DateTime,
* episodeFilesize: ?int, * episodeFilesize: ?int,
* episodeDuration: ?int, * episodeDuration: ?int
* episodeAction: ?EpisodeActionType
* } * }
*/ */
class EpisodeActionExtraData implements \JsonSerializable class EpisodeActionExtraData implements \JsonSerializable
@ -39,8 +38,7 @@ class EpisodeActionExtraData implements \JsonSerializable
private string $episodeGuid, private string $episodeGuid,
private ?\DateTime $episodePubDate, private ?\DateTime $episodePubDate,
private ?int $episodeFilesize, private ?int $episodeFilesize,
private ?int $episodeDuration, private ?int $episodeDuration
private ?EpisodeAction $episodeAction
) { ) {
$this->episodeUrl = $episodeUrl; $this->episodeUrl = $episodeUrl;
$this->podcastName = $podcastName; $this->podcastName = $podcastName;
@ -53,7 +51,6 @@ class EpisodeActionExtraData implements \JsonSerializable
$this->episodePubDate = $episodePubDate; $this->episodePubDate = $episodePubDate;
$this->episodeFilesize = $episodeFilesize; $this->episodeFilesize = $episodeFilesize;
$this->episodeDuration = $episodeDuration; $this->episodeDuration = $episodeDuration;
$this->episodeAction = $episodeAction;
} }
public function __toString(): string public function __toString(): string
@ -81,11 +78,6 @@ class EpisodeActionExtraData implements \JsonSerializable
return $this->episodeDuration; return $this->episodeDuration;
} }
public function getEpisodeAction(): ?EpisodeAction
{
return $this->episodeAction;
}
public function getEpisodeUrl(): ?string public function getEpisodeUrl(): ?string
{ {
return $this->episodeUrl; return $this->episodeUrl;
@ -109,7 +101,6 @@ class EpisodeActionExtraData implements \JsonSerializable
'episodePubDate' => $this->episodePubDate, 'episodePubDate' => $this->episodePubDate,
'episodeFilesize' => $this->episodeFilesize, 'episodeFilesize' => $this->episodeFilesize,
'episodeDuration' => $this->episodeDuration, 'episodeDuration' => $this->episodeDuration,
'episodeAction' => $this->episodeAction ? $this->episodeAction->toArray() : null,
]; ];
} }

View File

@ -4,18 +4,8 @@ declare(strict_types=1);
namespace OCA\RePod\Core\EpisodeAction; namespace OCA\RePod\Core\EpisodeAction;
use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader as GPodderSyncEpisodeActionReader; class EpisodeActionReader
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
use OCA\RePod\Service\UserService;
class EpisodeActionReader extends GPodderSyncEpisodeActionReader
{ {
public function __construct(
private EpisodeActionRepository $episodeActionRepository,
private UserService $userService
) {
}
/** /**
* https://github.com/pbek/nextcloud-nextpod/blob/main/lib/Core/EpisodeAction/EpisodeActionExtraData.php#L119. * https://github.com/pbek/nextcloud-nextpod/blob/main/lib/Core/EpisodeAction/EpisodeActionExtraData.php#L119.
* *
@ -46,9 +36,6 @@ class EpisodeActionReader extends GPodderSyncEpisodeActionReader
// Get episode filesize // Get episode filesize
$episodeFilesize = (int) $item->enclosure['length']; $episodeFilesize = (int) $item->enclosure['length'];
// Get episode action
$episodeAction = $this->episodeActionRepository->findByEpisodeUrl($episodeUrl, $this->userService->getUserUID());
// Get episode name // Get episode name
$episodeName = $this->stringOrNull($item->title); $episodeName = $this->stringOrNull($item->title);
@ -126,8 +113,7 @@ class EpisodeActionReader extends GPodderSyncEpisodeActionReader
$episodeGuid, $episodeGuid,
$episodePubDate, $episodePubDate,
$episodeFilesize, $episodeFilesize,
$episodeDuration, $episodeDuration
$episodeAction
); );
} }

View File

@ -66,7 +66,7 @@ export default {
async mounted() { async mounted() {
try { try {
this.loading = true this.loading = true
const episodes = await axios.get(generateUrl('/apps/repod/episodes?url={url}', { url: this.url })) const episodes = await axios.get(generateUrl('/apps/repod/episodes/list?url={url}', { url: this.url }))
this.episodes = episodes.data this.episodes = episodes.data
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -82,7 +82,7 @@ export default {
return this.currentEpisode && this.currentEpisode.episodeUrl === episode.episodeUrl return this.currentEpisode && this.currentEpisode.episodeUrl === episode.episodeUrl
}, },
load(episode) { load(episode) {
this.$store.commit('player/load', episode) this.$store.dispatch('player/load', episode)
}, },
}, },
} }

View File

@ -17,6 +17,7 @@ audio.onvolumechange = () => store.commit('player/volume', audio.volume)
export const player = { export const player = {
namespaced: true, namespaced: true,
state: { state: {
action: null,
currentTime: null, currentTime: null,
duration: null, duration: null,
episode: null, episode: null,
@ -26,13 +27,20 @@ export const player = {
volume: null, volume: null,
}, },
mutations: { mutations: {
action: (state, action) => {
state.action = action
if (action && action.position) {
audio.currentTime = action.position
}
},
currentTime: (state, currentTime) => { currentTime: (state, currentTime) => {
state.currentTime = currentTime state.currentTime = currentTime
}, },
duration: (state, duration) => { duration: (state, duration) => {
state.duration = duration state.duration = duration
}, },
load: (state, episode) => { episode: (state, episode) => {
state.episode = episode state.episode = episode
if (episode) { if (episode) {
@ -40,10 +48,6 @@ export const player = {
audio.src = episode.episodeUrl audio.src = episode.episodeUrl
audio.load() audio.load()
audio.play() audio.play()
if (episode.episodeAction) {
audio.currentTime = episode.episodeAction.position
}
} else { } else {
state.loaded = false state.loaded = false
state.podcastUrl = null state.podcastUrl = null
@ -61,6 +65,11 @@ export const player = {
}, },
}, },
actions: { actions: {
load: async (context, episode) => {
context.commit('episode', episode)
const action = await axios.get(generateUrl('/apps/repod/episodes/action?url={url}', { url: episode.episodeUrl }))
context.commit('action', action.data)
},
pause: (context) => { pause: (context) => {
audio.pause() audio.pause()
axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [{ axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [{
@ -69,7 +78,7 @@ export const player = {
guid: context.state.episode.episodeGuid, guid: context.state.episode.episodeGuid,
action: 'play', action: 'play',
timestamp: formatEpisodeTimestamp(new Date()), timestamp: formatEpisodeTimestamp(new Date()),
started: Math.round(context.state.episode.episodeAction ? context.state.episode.episodeAction.started : 0), started: Math.round(context.state.action ? context.state.action.started : 0),
position: Math.round(audio.currentTime), position: Math.round(audio.currentTime),
total: Math.round(audio.duration), total: Math.round(audio.duration),
}]) }])
@ -80,7 +89,8 @@ export const player = {
}, },
stop: (context) => { stop: (context) => {
context.dispatch('pause') context.dispatch('pause')
context.commit('load', null) context.commit('episode', null)
context.commit('action', null)
}, },
volume: (context, volume) => { volume: (context, volume) => {
audio.volume = volume audio.volume = volume