From fde3bd94743b4ab64276aafe2c71b81b77615ba8 Mon Sep 17 00:00:00 2001
From: Florence Randaxhe <43472197+FlorenceRandaxhe@users.noreply.github.com>
Date: Thu, 21 Aug 2025 17:29:53 +0200
Subject: [PATCH 1/4] added video component
---
components/video/Component.php | 33 +++++++++++++
components/video/Layout.php | 73 +++++++++++++++++++++++++++++
components/video/js.js | 69 +++++++++++++++++++++++++++
components/video/style.scss | 52 ++++++++++++++++++++
components/video/view.blade.php | 16 +++++++
src/Components/Publishers/Video.php | 65 +++++++++++++++++++++++++
6 files changed, 308 insertions(+)
create mode 100644 components/video/Component.php
create mode 100644 components/video/Layout.php
create mode 100644 components/video/js.js
create mode 100644 components/video/style.scss
create mode 100644 components/video/view.blade.php
create mode 100644 src/Components/Publishers/Video.php
diff --git a/components/video/Component.php b/components/video/Component.php
new file mode 100644
index 0000000..f64ca38
--- /dev/null
+++ b/components/video/Component.php
@@ -0,0 +1,33 @@
+image = $image;
+ $this->videoId = $videoId;
+ $this->caption = $caption;
+ }
+
+ /**
+ * Get the view / contents that represent the component.
+ */
+ public function render(): View|Closure|string
+ {
+ return view('components.video');
+ }
+}
diff --git a/components/video/Layout.php b/components/video/Layout.php
new file mode 100644
index 0000000..7d17cf1
--- /dev/null
+++ b/components/video/Layout.php
@@ -0,0 +1,73 @@
+fields([
+ HikerImage::make('Cover image', 'image')
+ ->rules('required')
+ ->disk('public'),
+
+ Text::make('YouTube identifier', 'videoId')
+ ->rules('required')
+ ->help('The YouTube identifier is the set of characters following the "watch?v=" in the video url. Ex: in the link https://www.youtube.com/watch?v=A6AxD9bUk1o, the identifier is A6AxD9bUk1o.'),
+
+ Text::make('Caption', 'caption')
+ ->help('Optionnal.'),
+ ]),
+ ];
+ }
+
+ /**
+ * The layout's display components
+ */
+ public function display(): array
+ {
+ return [
+ DataList::make()
+ ->row('YouTube identifier', TextComponent::make($this->videoId))
+ ->row('Image', ImageComponent::make(Storage::url($this->image))->aspectRatio('16/9'))
+ ->row('Caption', TextComponent::make($this->caption))
+ ->row('Alternative text', TextComponent::make($this->alt)),
+ ];
+ }
+
+ /**
+ * Extract the values from the bag to store them in the database.
+ */
+ public function fillAttributes(Baggage $bag): array
+ {
+ return $bag->only(['image', 'alt', 'caption', 'videoId']);
+ }
+}
diff --git a/components/video/js.js b/components/video/js.js
new file mode 100644
index 0000000..443d56f
--- /dev/null
+++ b/components/video/js.js
@@ -0,0 +1,69 @@
+export default class Video {
+ static selector = ".video";
+
+ constructor(el) {
+ this.el = el;
+ this.getElements();
+ this.setEvents();
+ this.player = null;
+ this.playerReady = false;
+
+ this.initIframe();
+ }
+
+ getElements() {
+ this.overlay = this.el.querySelector(".video__overlay-container");
+ this.playButton = this.el.querySelector(".video .button");
+ this.videoIframe = this.el.querySelector(".video__iframe");
+ }
+
+ setEvents() {
+ this.playButton.addEventListener("click", (e) => {
+ e.preventDefault();
+ this.toggleVideo();
+ });
+ }
+
+ initIframe() {
+ const tag = document.createElement("script");
+ tag.src = "https://www.youtube.com/iframe_api";
+ const firstScriptTag = document.getElementsByTagName("script")[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+ }
+
+ loadIframe() {
+ this.player = new YT.Player("player", {
+ height: "360",
+ width: "640",
+ videoId: this.el.dataset.videoId,
+ events: {
+ onReady: this.onPlayerReady,
+ onStateChange: this.onPlayerStateChange,
+ },
+ });
+ }
+
+ toggleVideo() {
+ if (!this.player || !this.playerReady) return;
+
+ this.overlay.classList.add("video__overlay-container--playing");
+
+ this.player.playVideo();
+ }
+
+ onPlayerReady = (event) => {
+ this.playerReady = true;
+ };
+
+ onPlayerStateChange = (event) => {
+ if (event.data === YT.PlayerState.ENDED) {
+ this.overlay.classList.remove("video__overlay-container--playing");
+ }
+ };
+}
+
+function onYouTubeIframeAPIReady() {
+ window.app.pluton.call(".video", "loadIframe");
+}
+
+window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;
diff --git a/components/video/style.scss b/components/video/style.scss
new file mode 100644
index 0000000..9f4a9c5
--- /dev/null
+++ b/components/video/style.scss
@@ -0,0 +1,52 @@
+.video {
+ margin: rem(54) 0;
+
+ &__container {
+ position: relative;
+ }
+
+ &__iframe-container {
+ @include respVideoContainer(12, 12);
+ }
+
+ &__overlay-container {
+ position: absolute;
+ z-index: 10;
+ width: 100%;
+ padding-bottom: 56.25%;
+ height: 0;
+ transition: opacity 1s;
+ visibility: visible;
+ opacity: 1;
+
+ &--playing {
+ opacity: 0;
+ transition: opacity 1s, visibility 0s 1s;
+ visibility: hidden;
+ }
+ }
+
+
+ &__overlay,
+ &__btn {
+ position: absolute;
+ display: grid;
+ align-items: center;
+ justify-items: center;
+ @include icon("elipse");
+ }
+
+ &__overlay {
+ background-size: cover;
+ background-position: center;
+ width: 100%;
+ height: 100%;
+ @include cover();
+ }
+
+ &__caption {
+ font-size: rem(12);
+ line-height: 130%;
+ margin-top: rem(8);
+ }
+}
diff --git a/components/video/view.blade.php b/components/video/view.blade.php
new file mode 100644
index 0000000..3e5e00a
--- /dev/null
+++ b/components/video/view.blade.php
@@ -0,0 +1,16 @@
+
+
+ @if($caption)
+
{{ $caption }}
+ @endif
+
diff --git a/src/Components/Publishers/Video.php b/src/Components/Publishers/Video.php
new file mode 100644
index 0000000..2d0469e
--- /dev/null
+++ b/src/Components/Publishers/Video.php
@@ -0,0 +1,65 @@
+`";
+ }
+}
From dc1bd52424cdd37c7f08e59441512ec363f49c4c Mon Sep 17 00:00:00 2001
From: Florence Randaxhe <43472197+FlorenceRandaxhe@users.noreply.github.com>
Date: Mon, 25 Aug 2025 10:55:02 +0200
Subject: [PATCH 2/4] updated video component
---
components/video/Component.php | 1 -
components/video/Layout.php | 5 ++---
components/video/js.js | 2 +-
components/video/style.scss | 13 ++++++++++---
components/video/view.blade.php | 5 ++---
5 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/components/video/Component.php b/components/video/Component.php
index f64ca38..9f651fb 100644
--- a/components/video/Component.php
+++ b/components/video/Component.php
@@ -12,7 +12,6 @@ class Video extends Component
public string $videoId;
public ?string $caption = null;
-
/**
* Create a new component instance.
*/
diff --git a/components/video/Layout.php b/components/video/Layout.php
index 7d17cf1..d55f3a4 100644
--- a/components/video/Layout.php
+++ b/components/video/Layout.php
@@ -56,10 +56,9 @@ public function display(): array
{
return [
DataList::make()
- ->row('YouTube identifier', TextComponent::make($this->videoId))
->row('Image', ImageComponent::make(Storage::url($this->image))->aspectRatio('16/9'))
+ ->row('YouTube identifier', TextComponent::make($this->videoId))
->row('Caption', TextComponent::make($this->caption))
- ->row('Alternative text', TextComponent::make($this->alt)),
];
}
@@ -68,6 +67,6 @@ public function display(): array
*/
public function fillAttributes(Baggage $bag): array
{
- return $bag->only(['image', 'alt', 'caption', 'videoId']);
+ return $bag->only(['image', 'caption', 'videoId']);
}
}
diff --git a/components/video/js.js b/components/video/js.js
index 443d56f..28f19f6 100644
--- a/components/video/js.js
+++ b/components/video/js.js
@@ -13,7 +13,7 @@ export default class Video {
getElements() {
this.overlay = this.el.querySelector(".video__overlay-container");
- this.playButton = this.el.querySelector(".video .button");
+ this.playButton = this.el.querySelector(".video .icon-button");
this.videoIframe = this.el.querySelector(".video__iframe");
}
diff --git a/components/video/style.scss b/components/video/style.scss
index 9f4a9c5..5946795 100644
--- a/components/video/style.scss
+++ b/components/video/style.scss
@@ -1,5 +1,6 @@
.video {
- margin: rem(54) 0;
+ margin: 0 auto;
+ width: col(6, 12);
&__container {
position: relative;
@@ -26,14 +27,12 @@
}
}
-
&__overlay,
&__btn {
position: absolute;
display: grid;
align-items: center;
justify-items: center;
- @include icon("elipse");
}
&__overlay {
@@ -49,4 +48,12 @@
line-height: 130%;
margin-top: rem(8);
}
+
+ @include mq($until: l) {
+ width: col(10, 12);
+ }
+
+ @include mq($until: s) {
+ width: auto;
+ }
}
diff --git a/components/video/view.blade.php b/components/video/view.blade.php
index 3e5e00a..5861e0f 100644
--- a/components/video/view.blade.php
+++ b/components/video/view.blade.php
@@ -1,9 +1,8 @@
-
From c61be1762558ce107ce8cb1fae0f0c18c820c6d8 Mon Sep 17 00:00:00 2001
From: Florence Randaxhe <43472197+FlorenceRandaxhe@users.noreply.github.com>
Date: Mon, 25 Aug 2025 11:21:59 +0200
Subject: [PATCH 3/4] Update style.scss
---
components/video/style.scss | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/components/video/style.scss b/components/video/style.scss
index 5946795..d181490 100644
--- a/components/video/style.scss
+++ b/components/video/style.scss
@@ -1,5 +1,5 @@
.video {
- margin: 0 auto;
+ margin: rem(32) auto;
width: col(6, 12);
&__container {
@@ -46,7 +46,7 @@
&__caption {
font-size: rem(12);
line-height: 130%;
- margin-top: rem(8);
+ margin-top: rem(12);
}
@include mq($until: l) {
From 1b6626ff242686f4b1c1391c62aa195c9ae1ba6f Mon Sep 17 00:00:00 2001
From: Florence Randaxhe <43472197+FlorenceRandaxhe@users.noreply.github.com>
Date: Tue, 26 Aug 2025 14:57:37 +0200
Subject: [PATCH 4/4] updated thumb name
---
components/video/Component.php | 6 +++---
components/video/Layout.php | 6 +++---
components/video/view.blade.php | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/components/video/Component.php b/components/video/Component.php
index 9f651fb..3184eb9 100644
--- a/components/video/Component.php
+++ b/components/video/Component.php
@@ -8,16 +8,16 @@
class Video extends Component
{
- public string $image;
+ public string $thumb;
public string $videoId;
public ?string $caption = null;
/**
* Create a new component instance.
*/
- public function __construct(string $image, string $videoId, string $caption = null)
+ public function __construct(string $thumb, string $videoId, string $caption = null)
{
- $this->image = $image;
+ $this->thumb = $thumb;
$this->videoId = $videoId;
$this->caption = $caption;
}
diff --git a/components/video/Layout.php b/components/video/Layout.php
index d55f3a4..9e246e5 100644
--- a/components/video/Layout.php
+++ b/components/video/Layout.php
@@ -35,7 +35,7 @@ public function form(Baggage $bag): array
return [
Step::make(static::label(), 'edit_video_layout')
->fields([
- HikerImage::make('Cover image', 'image')
+ HikerImage::make('Cover image', 'thumb')
->rules('required')
->disk('public'),
@@ -56,7 +56,7 @@ public function display(): array
{
return [
DataList::make()
- ->row('Image', ImageComponent::make(Storage::url($this->image))->aspectRatio('16/9'))
+ ->row('Cover image', ImageComponent::make(Storage::url($this->thumb))->aspectRatio('16/9'))
->row('YouTube identifier', TextComponent::make($this->videoId))
->row('Caption', TextComponent::make($this->caption))
];
@@ -67,6 +67,6 @@ public function display(): array
*/
public function fillAttributes(Baggage $bag): array
{
- return $bag->only(['image', 'caption', 'videoId']);
+ return $bag->only(['thumb', 'caption', 'videoId']);
}
}
diff --git a/components/video/view.blade.php b/components/video/view.blade.php
index 5861e0f..bda8b54 100644
--- a/components/video/view.blade.php
+++ b/components/video/view.blade.php
@@ -1,7 +1,7 @@