Skip to content
Snippets Groups Projects
Commit 62af2963 authored by Camille Simiand's avatar Camille Simiand
Browse files

Replace project preview by video preview first frame

parent c429b876
No related branches found
No related tags found
1 merge request!49tuleap-139-fix-capsule-time-loading-regression
assets/images/project_not_found.jpg

4.81 KiB

......@@ -10,6 +10,7 @@ use App\Helper\StringHelper;
use App\Repository\CapsuleRepository;
use App\Builder\CapsuleBuilder;
use App\Form\CreateCapsuleFormType;
use App\Retriever\ProjectRetriever;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Filesystem\Filesystem;
......@@ -22,10 +23,14 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class CapsuleController extends AbstractController
{
private CapsuleRepository $capsule_repository;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
public function __construct(
CapsuleRepository $capsule_repository,
TranslatorInterface $translator
) {
$this->capsule_repository = $capsule_repository;
$this->translator = $translator;
}
......@@ -94,7 +99,7 @@ class CapsuleController extends AbstractController
{
$file_path = '../legacy/' . $path;
if (!file_exists($file_path)) {
return $this->render('capsule/capsule_not_found.html.twig');
return $this->render('project/project_not_found.html.twig');
}
$url = $this->getParameter('app.legacy_external_prefix') . '/' . $path . "/?w=1";
......@@ -105,10 +110,35 @@ class CapsuleController extends AbstractController
);
}
/**
* @Route("capsule/{capsule_id}/video_preview", name="video_preview")
*/
public function videoPreview(int $capsule_id): Response
{
chdir('../legacy/');
$file_system = new Filesystem();
$capsule = $this->capsule_repository->findOneBy(['id' => $capsule_id]);
if (! $capsule instanceof Capsule) {
throw new \Exception('The retrieved capsule is not an instance of Capsule.');
}
if (! $file_system->exists($capsule->getLinkPath())) {
return $this->render('project/project_not_found.html.twig');
}
$video_preview_image_link = $this->getVideoPreviewImageLink($capsule);
return $this->render(
'project/project_preview.html.twig',
['video_preview_url' => $video_preview_image_link]
);
}
/**
* @Route("capsule/edit/{path}", name="edit_capsule")
*/
public function edit(string $path, CapsuleRepository $capsuleRepository, TranslatorInterface $translator): Response
public function edit(string $path): Response
{
$current_user = $this->getUser();
......@@ -116,8 +146,7 @@ class CapsuleController extends AbstractController
return $this->redirectToRoute('app_logout');
}
$capsule = $capsuleRepository->findOneBy(['link_path' => $path]);
$capsule = $this->capsule_repository->findOneBy(['link_path' => $path]);
if (null === $capsule) {
$this->addFlash('warning', $translator->trans('capsule.edit.not_found'));
return $this->redirectToRoute('capsule_list');
......@@ -130,7 +159,7 @@ class CapsuleController extends AbstractController
$file_path = '../legacy/' . $path;
if (!file_exists($file_path)) {
return $this->render('capsule/capsule_not_found.html.twig');
return $this->render('project/project_not_found.html.twig');
}
$url = $this->getParameter('app.legacy_external_prefix') . '/' . $capsule->getEditionLink();
......@@ -298,4 +327,17 @@ class CapsuleController extends AbstractController
return $capsule;
}
private function getVideoPreviewImageLink(Capsule $capsule): string
{
$project_retriever = new ProjectRetriever($capsule);
$video_url = $project_retriever->getVideoUrl();
$video_id = $project_retriever->getVideoId($video_url);
if (strpos($video_url, 'yout') !== false) {
return 'https://img.youtube.com/vi/' . $video_id . '/maxresdefault.jpg';
}
return 'https://vumbnail.com/' . $video_id . '.jpg';
}
}
......@@ -3,10 +3,12 @@
namespace App\Entity;
use App\Entity\User;
use App\Retriever\ProjectRetriever;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\User\UserInterface;
/**
......
<?php
namespace App\Retriever;
use App\Entity\Capsule;
class ProjectRetriever
{
private Capsule $capsule;
public function __construct(Capsule $capsule)
{
$this->capsule = $capsule;
}
private static function getDomDocument(): \DOMDocument
{
chdir('../legacy/');
$dom_xml = new \DOMDocument();
$dom_xml->preserveWhiteSpace = false;
return $dom_xml;
}
public function getVideoUrl(): string
{
$dom_xml = self::getDomDocument();
$dom_xml->load($this->capsule->getLinkPath() . '/file/project.xml');
$video_node = $dom_xml->getElementsByTagName('video')->item(0);
if ($video_node === null) {
throw new \Exception("Video node could not be found in XML project file");
}
return $video_node->getAttribute('url');
}
public function getVideoId(string $video_url): string
{
if (strpos($video_url, "vimeo")) {
return $this->getVimeoVideoIdFromUrl($video_url);
}
return $this->getYoutubeVideoIdFromUrl($video_url);
}
private function getYoutubeVideoIdFromUrl(string $video_url): string
{
$pattern = "#(?<=v=|v\/|vi=|vi\/|youtu.be\/)[a-zA-Z0-9_-]{11}#";
$result = preg_match($pattern, $video_url, $matches);
$video_id = "";
if (false !== $result) {
$video_id = $matches[0];
}
return $video_id;
}
private function getVimeoVideoIdFromUrl(string $video_url): string
{
$video_id = "";
$pattern = "/https?:\/\/(?:www\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|)(\d+)(?:$|\/|\?)/"; //phpcs:ignore
if (preg_match($pattern, $video_url, $id)) {
$video_id = $id[3];
}
return $video_id;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}MemoRekall{% endblock %}</title>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('build/images/favicon.ico') }}" />
</head>
<body class="container col-10 col-md-8 col-lg-6 m-auto">
<div class="position-relative d-flex flex-row align-items-center justify-content-center mb-5">
<img id="header-memorekall-logo" class="memorekall-logo" src="{{ asset('build/images/MemoRekall.png') }}">
</div>
<div class="m-auto d-flex flex-row align-items-center justify-content-center mb-5 alert alert-warning" role="status">
<span class="p-5">{{ 'capsule.not_found' | trans }}</span>
</div>
</body>
</html>
......@@ -56,12 +56,21 @@
<div class="d-flex flex-column flex-md-row justify-content-center align-items-center">
<div class="m-4 ratio ratio-16x9">
<iframe
src="/capsule/preview/{{ capsule.getLinkPath() }}"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
{# <img src="{{ capsule.getVideoPreviewImageLink() }}" alt="video preview">#}
{# <img src="/capsule/{{ capsule.getId() }}/video_preview" alt="video preview">#}
</div>
{# {% if 'yout' in video_url %}#}
{# <img src="https://img.youtube.com/vi/{{ capsule.getVideoId() }}maxresdefault.jpg">#}
{# {% else %}#}
{# <img src="https://vumbnail.com/{{ capsule.getVideoId() }}.jpg">#}
{# <div class="m-4 ratio ratio-16x9">#}
{# <iframe#}
{# src="/capsule/preview/{{ capsule.getLinkPath() }}"#}
{# allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"#}
{# allowfullscreen>#}
{# </iframe>#}
{# </div>#}
<div class="d-flex flex-column justify-content-center m-2 pe-2">
<i class="fa-thin fa-gears"></i>
......
{% extends 'layout.html.twig' %}
{% block title %}
{{ 'project.not_found'|trans }}
-
{{ parent() }}
{% endblock %}
{% block body %}
<div class="col-10 col-md-8 col-lg-6 col-xl-5 col-xxl-6 m-auto d-flex flex-row align-items-center justify-content-center mb-5 alert alert-warning" role="status">
<span class="p-5">{{ 'project.not_found' | trans }}</span>
</div>
{% endblock %}
\ No newline at end of file
......@@ -45,7 +45,7 @@ class CapsuleControllerTest extends WebTestCase
$submit_button = $crawler->selectButton('Create a capsule');
$form = $submit_button->form();
$video_url = "https://TestUrl";
$video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley";
$form['create_capsule_form[name]'] = self::CAPSULE_NAME;
$form['create_capsule_form[video_url]'] = $video_url;
......
......@@ -114,46 +114,3 @@ user:
updated_success: The password has been updated
edit_profile: Edit my profile
edit_password: Edit my password
\ No newline at end of file
editors:
title: Editors
title_name: Editors of capsule %capsule_name%
add_email_address: Add new editor with email address
current_editors_title: Current editors
pending_editors_title: Pending editors
user_not_editor_error: You are not editor of the capsule
add:
pending_editor:
success: The user user_email has been added to pending editor list.
He will receive an email to invite him register on MemoRekall and to inform him he has been added as an editor of this capsule.
already_added: The user user_email has already been added to pending editor list
email:
title: Invitation to edit a MemoRekall capsule
text: You have been added by %user_name% as editor of the capsule "%capsule_name%".
In order to access and edit it, you first need to register on MemoRekall. Please follow this link to
link: https://project.memorekall.com/register/
link_name: register
user:
success: The user user_email is now an editor of the capsule capsule_name.
He will receive an email to inform him he has been added as an editor of this capsule.
already_added: The user user_email is already an editor of this capsule
email:
title: New capsule on your list
text: You have been add by %user_name% as editor of the capsule "%capsule_name%".
You can now access and edit it. You will find the capsule in your capsule list.
link: Go to capsule edition page
remove:
button: Remove
pending_editor:
title: Remove pending editor
text: Do you really want to delete pending editor %editor_email%?
link: Remove pending editor
error: The email address has already been removed from pending editors of the capsule capsule_name
success: The email address pending_editor_email has been successfully removed from pending editors of the capsule capsule_name
editor:
title: Remove editor
text: Do you really want to delete editor %editor_email%?
link: Remove editor
success: User editor_email is no longer and editor of the capsule capsule_name
error: You can't remove yourself as editor of your own capsule.
If you want to remove the capsule from your list, go to the capsule list page and click on "delete capsule"
\ No newline at end of file
......@@ -62,6 +62,7 @@ capsule:
created_success: La capsule capsule_name a été créée
no_edition_access: Pas d'accès au mode édition
contact_capsule_author_for_access: Veuillez contacter l'auteur de la capsule pour lui demander son accès en mode édition
not_found: Le projet n'existe pas
edit_permissions:
link: Modifier les permissions
edit:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment