Skip to content

Commit

Permalink
Update vue stuff, add apis
Browse files Browse the repository at this point in the history
  • Loading branch information
pkly committed Feb 11, 2024
1 parent b88af6c commit 1034e26
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 29 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"@types/lodash": "^4.14.202",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"pinia": "^2.1.7",
Expand Down
1 change: 0 additions & 1 deletion src/Command/RssSearchCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;

#[AsCommand(
Expand Down
41 changes: 40 additions & 1 deletion src/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

namespace App\Controller;

use App\Entity\Rss\Result;
use App\Repository\Rss\ResultRepository;
use App\Service\MascotService;
use App\Service\QBitTorrentService;
use App\Service\SplashTitleService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;

Expand All @@ -29,4 +33,39 @@ public function getRssFinds(
],
]);
}
}

#[Route('/download-rss/{result}', name: 'download_rss', methods: ['GET'])]
public function downloadRss(
QBitTorrentService $service,
Result $result,
ResultRepository $repository
): Response {
if (!$service->addTorrent($result)) {
return new Response(status: Response::HTTP_FORBIDDEN);
}

// busy waiting to make it real
$attempts = 10;

while ($attempts > 0) {
$attempts--;

if (null === ($result = $repository->find($result->getId()))) {
return new Response(status: Response::HTTP_NOT_FOUND);
}

if (null !== $result->getSeenAt()) {
return new Response();
}
}

return new Response(status: Response::HTTP_TOO_MANY_REQUESTS);
}

#[Route('/page-titles', name: 'page_titles', methods: ['GET'])]
public function getPageTitles(
SplashTitleService $service
): JsonResponse {
return $this->json($service->getTitles());
}
}
30 changes: 12 additions & 18 deletions src/Entity/Rss/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use App\Repository\Rss\ResultRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Context;
use Symfony\Component\Serializer\Attribute\Groups;

#[ORM\Entity(repositoryClass: ResultRepository::class)]
Expand Down Expand Up @@ -40,7 +39,7 @@ class Result

#[ORM\Column(type: Types::DATETIME_IMMUTABLE, options: ['default' => 'NOW()'])]
#[Groups('api')]
private ?\DateTimeImmutable $createdAt = null;
private \DateTimeImmutable|null $createdAt = null;

public function getId(): int|null
{
Expand All @@ -54,8 +53,7 @@ public function getUrl(): string|null

public function setUrl(
string $url
): self
{
): self {
$this->url = $url;

return $this;
Expand All @@ -68,8 +66,7 @@ public function getTitle(): string|null

public function setTitle(
string $title
): self
{
): self {
$this->title = $title;

return $this;
Expand All @@ -82,8 +79,7 @@ public function getData(): array|null

public function setData(
array $data
): self
{
): self {
$this->data = $data;

return $this;
Expand All @@ -96,8 +92,7 @@ public function getSeenAt(): \DateTimeImmutable|null

public function setSeenAt(
\DateTimeImmutable|null $seenAt
): self
{
): self {
$this->seenAt = $seenAt;

return $this;
Expand All @@ -110,8 +105,7 @@ public function getGuid(): string|null

public function setGuid(
string $guid
): self
{
): self {
$this->guid = $guid;

return $this;
Expand All @@ -124,22 +118,22 @@ public function getSearch(): Search|null

public function setSearch(
Search|null $search
): self
{
): self {
$this->search = $search;

return $this;
}

public function getCreatedAt(): ?\DateTimeImmutable
public function getCreatedAt(): \DateTimeImmutable|null
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
public function setCreatedAt(
\DateTimeImmutable $createdAt
): static {
$this->createdAt = $createdAt;

return $this;
}
}
}
8 changes: 8 additions & 0 deletions src/Service/SplashTitleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ public function getTitle(): string
{
return self::TITLES[array_rand(self::TITLES)];
}

/**
* @return list<string>
*/
public function getTitles(): array
{
return self::TITLES;
}
}
2 changes: 1 addition & 1 deletion src/Twig/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ private function vueStyles(): array

return $files;
}
}
}
2 changes: 1 addition & 1 deletion vue/components/Mascot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let mascot = ref(null);
onMounted(async () => {
const store = useMascotStore();
await store.updateAvailable();
await store.fetchUpdateAsNeeded();
mascot.value = store.getCurrentMascot();
});
</script>
Expand Down
13 changes: 12 additions & 1 deletion vue/components/PageTitle.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
<script setup lang="ts">
import {onMounted, ref} from "vue";
import {useTitleStore} from "../stores/title";
const title = ref('~');
onMounted(async () => {
const store = useTitleStore();
await store.fetchUpdateAsNeeded();
title.value = store.getTitle();
})
</script>

<template>
<header class="mb-4">
Default page title!
{{ title }}
</header>
</template>

Expand Down
75 changes: 72 additions & 3 deletions vue/components/RssResult.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,86 @@
<script setup lang="ts">
import {ref} from "vue";
import moment from "moment";
import _ from "lodash";
const props = defineProps({
data: { type: Object, required: true },
});
const emit = defineEmits(['onSuccess']);
const busy = ref(false);
const success = ref(false);
const error = ref(false);
const id = ref(_.uniqueId());
async function request() {
if (busy.value) {
return;
}
busy.value = true;
const response = await fetch('/api/download-rss/' + props.data.id);
if (response.status === 200) {
success.value = true;
emit('onSuccess');
} else {
error.value = true;
}
}
</script>

<template>
<div class="rss">
<div class="header">{{props.data.title}}</div>
<div class="rss-wrapper" :class="{hide: success}">
<div class="rss mb-3" :id="id" @click="request" :class="{busy: busy, success: success, failure: error}">
<div class="row">
<div class="col-12 col-md-9">
<div class="header text-info">{{props.data.title}}</div>
</div>
<div class="col-12 col-md-3 text-end">
<small>{{moment(props.data.createdAt).fromNow()}}</small>
</div>
</div>
</div>
</div>
</template>

<style scoped>
<style scoped lang="scss">
.rss-wrapper {
overflow: hidden;
transition: 0.7s;
max-height: 100px;
&.hide {
max-height: 0;
}
}
.rss {
padding: 0.3rem;
border-bottom: var(--bs-info-border-subtle) 1px solid;
border-right: var(--bs-info-border-subtle) 1px solid;
&:hover {
cursor: pointer;
&.busy {
cursor: not-allowed;
}
}
transition: 0.6s;
&.failure {
background: var(--bs-danger);
border-color: var(--bs-danger-border-subtle);
}
&.success {
background: var(--bs-success);
border-color: var(--bs-success-border-subtle);
}
}
</style>
17 changes: 15 additions & 2 deletions vue/components/RssResultList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,34 @@ import RssResult from "./RssResult.vue";
import HeaderBlock from "./HeaderBlock.vue";
const data = ref([]);
const done = ref(false);
onMounted(async () => {
const response = await fetch('/api/rss');
data.value = await response.json();
});
const successes = ref(0);
function handleOnSuccess() {
successes.value++;
if (successes.value === data.value.length) {
setTimeout(() => {
done.value = true;
}, 5000);
}
}
</script>

<template>
<HeaderBlock v-if="data.length">
<HeaderBlock v-if="data.length && !done">
<template v-slot:header>
Some shit here
</template>
<template v-slot:default>
<RssResult v-for="d in data" :data="d" />
<RssResult v-for="(d, i) in data" :data="d" :key="i" @onSuccess="handleOnSuccess"/>
</template>
</HeaderBlock>
</template>
Expand Down
2 changes: 1 addition & 1 deletion vue/stores/mascot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const useMascotStore = defineStore('mascot', () => {
return group.mascots[currentIndex.value];
}

return {groups, currentGroup, currentIndex, lastIndexes, updateAvailable: fetchUpdateAsNeeded, changeGroup, getCurrentMascot};
return {groups, currentGroup, currentIndex, lastIndexes, fetchUpdateAsNeeded, changeGroup, getCurrentMascot};
}, {
persist: true
});
Loading

0 comments on commit 1034e26

Please sign in to comment.