From d18728561af6c7b0901f1e7d650bbc1a9368e53a Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Fri, 18 Aug 2023 15:13:54 +0200 Subject: [PATCH 1/8] Add video page link to video blocks --- frontend/src/i18n/locales/de.yaml | 1 + frontend/src/i18n/locales/en.yaml | 1 + frontend/src/ui/Blocks/Video.tsx | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/i18n/locales/de.yaml b/frontend/src/i18n/locales/de.yaml index 6d0297142..b406debd7 100644 --- a/frontend/src/i18n/locales/de.yaml +++ b/frontend/src/i18n/locales/de.yaml @@ -128,6 +128,7 @@ video: duration: Abspielzeit language_one: Sprache language_other: Sprachen + link: Videoseite part-of-series: Teil von Serie more-from-series: Mehr von „{{series}}“ deleted-video-block: Das hier referenzierte Video wurde gelöscht. diff --git a/frontend/src/i18n/locales/en.yaml b/frontend/src/i18n/locales/en.yaml index c374b26e1..837483f0d 100644 --- a/frontend/src/i18n/locales/en.yaml +++ b/frontend/src/i18n/locales/en.yaml @@ -125,6 +125,7 @@ video: duration: Duration language_one: Language language_other: Languages + link: Video page part-of-series: Part of series more-from-series: More from “{{series}}” deleted-video-block: The video referenced here was deleted. diff --git a/frontend/src/ui/Blocks/Video.tsx b/frontend/src/ui/Blocks/Video.tsx index 502032716..42f14b58c 100644 --- a/frontend/src/ui/Blocks/Video.tsx +++ b/frontend/src/ui/Blocks/Video.tsx @@ -6,7 +6,8 @@ import { VideoBlockData$key } from "./__generated__/VideoBlockData.graphql"; import { Title } from ".."; import { Card } from "../Card"; import { useTranslation } from "react-i18next"; -import { isSynced } from "../../util"; +import { isSynced, keyOfId } from "../../util"; +import { Link } from "../../router"; type Props = { @@ -21,6 +22,7 @@ export const VideoBlock: React.FC = ({ fragRef }) => { __typename ... on NotAllowed { dummy } # workaround ... on AuthorizedEvent { + id title isLive created @@ -55,5 +57,8 @@ export const VideoBlock: React.FC = ({ fragRef }) => { {isSynced(event) ? : {t("video.not-ready.title")}} + {t("video.link")} ; }; From 9422b4296446b4df2b3f9c610bc76e817d17b0be Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Fri, 25 Aug 2023 14:35:29 +0200 Subject: [PATCH 2/8] Add migration and necessary logic for video block links --- backend/src/api/model/block/mod.rs | 7 +++++++ backend/src/api/model/block/mutations.rs | 13 ++++++++----- backend/src/db/migrations.rs | 1 + .../src/db/migrations/23-video-block-show-link.sql | 10 ++++++++++ frontend/src/i18n/locales/de.yaml | 2 ++ frontend/src/i18n/locales/en.yaml | 2 ++ .../src/routes/manage/Realm/Content/AddButtons.tsx | 1 + .../manage/Realm/Content/Edit/EditMode/Video.tsx | 13 ++++++++++++- frontend/src/schema.graphql | 3 +++ frontend/src/ui/Blocks/Video.tsx | 7 ++++--- 10 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 backend/src/db/migrations/23-video-block-show-link.sql diff --git a/backend/src/api/model/block/mod.rs b/backend/src/api/model/block/mod.rs index f2ea3be79..68744258a 100644 --- a/backend/src/api/model/block/mod.rs +++ b/backend/src/api/model/block/mod.rs @@ -207,6 +207,7 @@ pub(crate) struct VideoBlock { // Is `None` if the video was removed from the DB. pub(crate) event: Option, pub(crate) show_title: bool, + pub(crate) show_link: bool, } impl Block for VideoBlock { @@ -230,6 +231,10 @@ impl VideoBlock { self.show_title } + fn show_link(&self) -> bool { + self.show_link + } + fn id(&self) -> Id { Block::id(self) } @@ -255,6 +260,7 @@ impl_from_db!( videolist_order, video, show_title, + show_link, show_metadata, realm, }, @@ -290,6 +296,7 @@ impl_from_db!( shared, event: row.video::>().map(Id::event), show_title: unwrap_type_dep(row.show_title(), "event", "show_title"), + show_link: unwrap_type_dep(row.show_link(), "event", "show_link"), }.into(), } } diff --git a/backend/src/api/model/block/mutations.rs b/backend/src/api/model/block/mutations.rs index 81829e5d1..3d6af92d7 100644 --- a/backend/src/api/model/block/mutations.rs +++ b/backend/src/api/model/block/mutations.rs @@ -82,9 +82,9 @@ impl BlockValue { context.db .execute( - "insert into blocks (realm, index, type, video, show_title) \ - values ($1, $2, 'video', $3, $4)", - &[&realm.key, &index, &event, &block.show_title], + "insert into blocks (realm, index, type, video, show_title, show_link) \ + values ($1, $2, 'video', $3, $4, $5)", + &[&realm.key, &index, &event, &block.show_title, &block.show_link], ) .await?; @@ -309,13 +309,14 @@ impl BlockValue { let query = format!( "update blocks set \ video = coalesce($2, video), \ - show_title = coalesce($3, show_title) \ + show_title = coalesce($3, show_title), \ + show_link = coalesce($4, show_link) \ where id = $1 \ and type = 'video' \ returning {selection}", ); context.db - .query_one(&query, &[&Self::key_for(id)?, &video_id, &set.show_title]) + .query_one(&query, &[&Self::key_for(id)?, &video_id, &set.show_title, &set.show_link]) .await? .pipe(|row| Ok(Self::from_row_start(&row))) } @@ -395,6 +396,7 @@ pub(crate) struct NewSeriesBlock { pub(crate) struct NewVideoBlock { event: Id, show_title: bool, + show_link: bool, } @@ -420,6 +422,7 @@ pub(crate) struct UpdateSeriesBlock { pub(crate) struct UpdateVideoBlock { event: Option, show_title: Option, + show_link: Option, } diff --git a/backend/src/db/migrations.rs b/backend/src/db/migrations.rs index faa71c3c8..8f69145dd 100644 --- a/backend/src/db/migrations.rs +++ b/backend/src/db/migrations.rs @@ -337,4 +337,5 @@ static MIGRATIONS: Lazy> = include_migrations![ 20: "fix-queue-triggers", 21: "fix-user-root-realm-name-block", 22: "user-email", + 23: "video-block-show-link", ]; diff --git a/backend/src/db/migrations/23-video-block-show-link.sql b/backend/src/db/migrations/23-video-block-show-link.sql new file mode 100644 index 000000000..3da9345bb --- /dev/null +++ b/backend/src/db/migrations/23-video-block-show-link.sql @@ -0,0 +1,10 @@ +-- Adds a single `show_link` field to blocks, used for video blocks to also show +-- a link to the corresponding video page. We also drop and re-add the appropriate constraint. +alter table blocks + add column show_link boolean default false, + drop constraint video_block_has_fields, + add constraint video_block_has_fields check (type <> 'video' or ( + show_title is not null and + show_link is not null + )); + \ No newline at end of file diff --git a/frontend/src/i18n/locales/de.yaml b/frontend/src/i18n/locales/de.yaml index b406debd7..626aa0b66 100644 --- a/frontend/src/i18n/locales/de.yaml +++ b/frontend/src/i18n/locales/de.yaml @@ -473,6 +473,8 @@ manage: titled: title: Titel show-title: Titel anzeigen + + show-link: Link anzeigen save: Speichern cancel: Verwerfen diff --git a/frontend/src/i18n/locales/en.yaml b/frontend/src/i18n/locales/en.yaml index 837483f0d..9e3943583 100644 --- a/frontend/src/i18n/locales/en.yaml +++ b/frontend/src/i18n/locales/en.yaml @@ -461,6 +461,8 @@ manage: title: Title show-title: Show title + show-link: Show link + save: Save cancel: Discard confirm-cancel: Discard changes? diff --git a/frontend/src/routes/manage/Realm/Content/AddButtons.tsx b/frontend/src/routes/manage/Realm/Content/AddButtons.tsx index 9c860f508..3d31650de 100644 --- a/frontend/src/routes/manage/Realm/Content/AddButtons.tsx +++ b/frontend/src/routes/manage/Realm/Content/AddButtons.tsx @@ -150,6 +150,7 @@ export const AddButtons: React.FC = ({ index, realm }) => { label={t("manage.realm.content.add-video")} onClick={() => addBlock("Video", (_store, block) => { block.setValue(true, "showTitle"); + block.setValue(false, "showLink"); })} /> diff --git a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx index 34d8290b8..6caa3b4a7 100644 --- a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx +++ b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx @@ -24,6 +24,7 @@ import { ErrorDisplay } from "../../../../../../util/err"; type VideoFormData = { event: string; showTitle: boolean; + showLink: boolean; }; type EditVideoBlockProps = { @@ -31,7 +32,7 @@ type EditVideoBlockProps = { }; export const EditVideoBlock: React.FC = ({ block: blockRef }) => { - const { event, showTitle } = useFragment(graphql` + const { event, showTitle, showLink } = useFragment(graphql` fragment VideoEditModeBlockData on VideoBlock { event { __typename, @@ -47,6 +48,7 @@ export const EditVideoBlock: React.FC = ({ block: blockRef } } showTitle + showLink } `, blockRef); @@ -106,6 +108,15 @@ export const EditVideoBlock: React.FC = ({ block: blockRef /> {t("manage.realm.content.titled.show-title")} + ; }; diff --git a/frontend/src/schema.graphql b/frontend/src/schema.graphql index 42b9464e0..193e12a8a 100644 --- a/frontend/src/schema.graphql +++ b/frontend/src/schema.graphql @@ -123,6 +123,7 @@ union EventSearchOutcome = SearchUnavailable | EventSearchResults input NewVideoBlock { event: ID! showTitle: Boolean! + showLink: Boolean! } type SyncedEventData { @@ -154,12 +155,14 @@ type NotAllowed { input UpdateVideoBlock { event: ID showTitle: Boolean + showLink: Boolean } "A block for presenting a single Opencast event" type VideoBlock implements Block & RealmNameSourceBlock { event: Event showTitle: Boolean! + showLink: Boolean! id: ID! index: Int! realm: Realm! diff --git a/frontend/src/ui/Blocks/Video.tsx b/frontend/src/ui/Blocks/Video.tsx index 42f14b58c..71900b049 100644 --- a/frontend/src/ui/Blocks/Video.tsx +++ b/frontend/src/ui/Blocks/Video.tsx @@ -16,7 +16,7 @@ type Props = { export const VideoBlock: React.FC = ({ fragRef }) => { const { t } = useTranslation(); - const { event, showTitle } = useFragment(graphql` + const { event, showTitle, showLink } = useFragment(graphql` fragment VideoBlockData on VideoBlock { event { __typename @@ -38,6 +38,7 @@ export const VideoBlock: React.FC = ({ fragRef }) => { } } showTitle + showLink } `, fragRef); @@ -57,8 +58,8 @@ export const VideoBlock: React.FC = ({ fragRef }) => { {isSynced(event) ? : {t("video.not-ready.title")}} - {t("video.link")} + >{t("video.link")}} ; }; From 4c0fc7b4bff20162ca7a325f36d85dbfe4db4f05 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Fri, 25 Aug 2023 15:53:11 +0200 Subject: [PATCH 3/8] Refactor display option checkboxes I don't think this was particularly necessary or useful, and it even results in more code than before, but oh well I guess it doesn't hurt either. This way the checkbox component is at least reusable... --- frontend/src/i18n/locales/de.yaml | 5 +- frontend/src/i18n/locales/en.yaml | 5 +- .../Realm/Content/Edit/EditMode/Video.tsx | 51 +++++++++++-------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/frontend/src/i18n/locales/de.yaml b/frontend/src/i18n/locales/de.yaml index 626aa0b66..93ca186e3 100644 --- a/frontend/src/i18n/locales/de.yaml +++ b/frontend/src/i18n/locales/de.yaml @@ -470,10 +470,7 @@ manage: no-read-access-to-current: > Sie haben keinen Lesezugriff zu dem derzeit verlinkten Video. - titled: - title: Titel - show-title: Titel anzeigen - + show-title: Titel anzeigen show-link: Link anzeigen save: Speichern diff --git a/frontend/src/i18n/locales/en.yaml b/frontend/src/i18n/locales/en.yaml index 9e3943583..9069c0652 100644 --- a/frontend/src/i18n/locales/en.yaml +++ b/frontend/src/i18n/locales/en.yaml @@ -457,10 +457,7 @@ manage: no-read-access-to-current: > You do not have read access to the video that is currently referenced here. - titled: - title: Title - show-title: Show title - + show-title: Show title show-link: Show link save: Save diff --git a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx index 6caa3b4a7..5effd4bb9 100644 --- a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx +++ b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx @@ -2,7 +2,7 @@ import React, { ReactNode, useState } from "react"; import { fetchQuery, graphql, useFragment, useMutation } from "react-relay"; import { useTranslation } from "react-i18next"; import { TFunction } from "i18next"; -import { Controller, useFormContext } from "react-hook-form"; +import { Controller, UseFormReturn, useFormContext } from "react-hook-form"; import { Card } from "../../../../../../ui/Card"; import { EditModeForm } from "."; @@ -81,6 +81,11 @@ export const EditVideoBlock: React.FC = ({ block: blockRef ? { ...event, ...event.syncedData, seriesTitle: event.series?.title } : undefined; + const optionProps: ["showTitle" | "showLink", boolean, string][] = [ + ["showTitle", showTitle, t("manage.realm.content.show-title")], + ["showLink", showLink, t("manage.realm.content.show-link")], + ]; + return data}> {t("manage.realm.content.event.event.heading")} {"event" in errors &&
@@ -98,28 +103,34 @@ export const EditVideoBlock: React.FC = ({ block: blockRef )} /> - {t("manage.realm.content.titled.title")} - - +
+ {optionProps.map(([option, checked, title]) => + // eslint-disable-next-line react/jsx-key + ) + } +
; }; +type DisplayOption = { + form: UseFormReturn; + option: "showTitle" | "showLink"; + checked: boolean; + title: string; +} + +const DisplayOption: React.FC = ( + { form, option, checked, title } +) => ; + type EventSelectorProps = { onChange: (eventId?: string) => void; onBlur: () => void; From f62525780008913e68fc9fdf9fdb09832230ecc4 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Wed, 30 Aug 2023 17:35:28 +0200 Subject: [PATCH 4/8] Clarify checkbox and button wording --- frontend/src/i18n/locales/de.yaml | 4 ++-- frontend/src/i18n/locales/en.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/i18n/locales/de.yaml b/frontend/src/i18n/locales/de.yaml index 93ca186e3..3bc3769f2 100644 --- a/frontend/src/i18n/locales/de.yaml +++ b/frontend/src/i18n/locales/de.yaml @@ -128,7 +128,7 @@ video: duration: Abspielzeit language_one: Sprache language_other: Sprachen - link: Videoseite + link: Zur Videoseite part-of-series: Teil von Serie more-from-series: Mehr von „{{series}}“ deleted-video-block: Das hier referenzierte Video wurde gelöscht. @@ -471,7 +471,7 @@ manage: Sie haben keinen Lesezugriff zu dem derzeit verlinkten Video. show-title: Titel anzeigen - show-link: Link anzeigen + show-link: Link zur Videoseite anzeigen save: Speichern cancel: Verwerfen diff --git a/frontend/src/i18n/locales/en.yaml b/frontend/src/i18n/locales/en.yaml index 9069c0652..899ac0b29 100644 --- a/frontend/src/i18n/locales/en.yaml +++ b/frontend/src/i18n/locales/en.yaml @@ -125,7 +125,7 @@ video: duration: Duration language_one: Language language_other: Languages - link: Video page + link: Go to video page part-of-series: Part of series more-from-series: More from “{{series}}” deleted-video-block: The video referenced here was deleted. @@ -458,7 +458,7 @@ manage: You do not have read access to the video that is currently referenced here. show-title: Show title - show-link: Show link + show-link: Show link to video page save: Save cancel: Discard From 93da0b47724fef5d9f585f7322303d9ec255e8b3 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Wed, 30 Aug 2023 17:36:12 +0200 Subject: [PATCH 5/8] Replace direkt link with contextual link --- frontend/src/ui/Blocks/Video.tsx | 12 ++++++++---- frontend/src/ui/Blocks/index.tsx | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/frontend/src/ui/Blocks/Video.tsx b/frontend/src/ui/Blocks/Video.tsx index 71900b049..2d87555df 100644 --- a/frontend/src/ui/Blocks/Video.tsx +++ b/frontend/src/ui/Blocks/Video.tsx @@ -8,13 +8,15 @@ import { Card } from "../Card"; import { useTranslation } from "react-i18next"; import { isSynced, keyOfId } from "../../util"; import { Link } from "../../router"; +import { FiArrowRightCircle } from "react-icons/fi"; type Props = { fragRef: VideoBlockData$key; + basePath: string; }; -export const VideoBlock: React.FC = ({ fragRef }) => { +export const VideoBlock: React.FC = ({ fragRef, basePath }) => { const { t } = useTranslation(); const { event, showTitle, showLink } = useFragment(graphql` fragment VideoBlockData on VideoBlock { @@ -58,8 +60,10 @@ export const VideoBlock: React.FC = ({ fragRef }) => { {isSynced(event) ? : {t("video.not-ready.title")}} - {showLink && {t("video.link")}} + {showLink && + {t("video.link")} + + } ; }; diff --git a/frontend/src/ui/Blocks/index.tsx b/frontend/src/ui/Blocks/index.tsx index 00d97e075..506375b2c 100644 --- a/frontend/src/ui/Blocks/index.tsx +++ b/frontend/src/ui/Blocks/index.tsx @@ -70,7 +70,7 @@ export const Block: React.FC = ({ block: blockRef, realm }) => { "TitleBlock": () => , "TextBlock": () => , "SeriesBlock": () => , - "VideoBlock": () => , + "VideoBlock": () => , })}
; }; From d7bc83bf2271e106710ec9753934ef896c302657 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Mon, 11 Sep 2023 17:26:47 +0200 Subject: [PATCH 6/8] Default to always show links --- frontend/src/routes/manage/Realm/Content/AddButtons.tsx | 2 +- .../src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/routes/manage/Realm/Content/AddButtons.tsx b/frontend/src/routes/manage/Realm/Content/AddButtons.tsx index 3d31650de..73a3ae5e2 100644 --- a/frontend/src/routes/manage/Realm/Content/AddButtons.tsx +++ b/frontend/src/routes/manage/Realm/Content/AddButtons.tsx @@ -150,7 +150,7 @@ export const AddButtons: React.FC = ({ index, realm }) => { label={t("manage.realm.content.add-video")} onClick={() => addBlock("Video", (_store, block) => { block.setValue(true, "showTitle"); - block.setValue(false, "showLink"); + block.setValue(true, "showLink"); })} /> diff --git a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx index 5effd4bb9..d0ae03c6c 100644 --- a/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx +++ b/frontend/src/routes/manage/Realm/Content/Edit/EditMode/Video.tsx @@ -103,10 +103,10 @@ export const EditVideoBlock: React.FC = ({ block: blockRef )} /> -
+
{optionProps.map(([option, checked, title]) => // eslint-disable-next-line react/jsx-key - ) + ) }
; From fdcaa1b9dee29250d19d599217b74c3dd0949738 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Mon, 11 Sep 2023 18:10:07 +0200 Subject: [PATCH 7/8] Right-align video link --- frontend/src/ui/Blocks/Video.tsx | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/frontend/src/ui/Blocks/Video.tsx b/frontend/src/ui/Blocks/Video.tsx index 2d87555df..1789f97ae 100644 --- a/frontend/src/ui/Blocks/Video.tsx +++ b/frontend/src/ui/Blocks/Video.tsx @@ -55,15 +55,25 @@ export const VideoBlock: React.FC = ({ fragRef, basePath }) => { return unreachable(); } - return <> + return
{showTitle && } {isSynced(event) ? <InlinePlayer event={event} css={{ maxWidth: 800 }} /> : <Card kind="info">{t("video.not-ready.title")}</Card>} - {showLink && <Link to={`${basePath}/${keyOfId(event.id)}`} + {showLink && <Link + to={`${basePath}/${keyOfId(event.id)}`} + css={{ + display: "flex", + alignItems: "center", + gap: 8, + marginTop: 8, + marginLeft: "auto", + width: "fit-content", + }} > {t("video.link")} - <FiArrowRightCircle /> - </Link>} - </>; + <FiArrowRightCircle size={18} css={{ marginTop: 1 }} /> + </Link> + } + </div>; }; From 67d939aa3b5984bf1ff9b9e80a5ab57ef128a842 Mon Sep 17 00:00:00 2001 From: Ole Wieners <olewieners@yahoo.com> Date: Tue, 12 Sep 2023 10:07:54 +0200 Subject: [PATCH 8/8] Show link by default on all video blocks --- backend/src/db/migrations/23-video-block-show-link.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/db/migrations/23-video-block-show-link.sql b/backend/src/db/migrations/23-video-block-show-link.sql index 3da9345bb..d6a904df6 100644 --- a/backend/src/db/migrations/23-video-block-show-link.sql +++ b/backend/src/db/migrations/23-video-block-show-link.sql @@ -1,10 +1,10 @@ -- Adds a single `show_link` field to blocks, used for video blocks to also show -- a link to the corresponding video page. We also drop and re-add the appropriate constraint. alter table blocks - add column show_link boolean default false, + add column show_link boolean default true, drop constraint video_block_has_fields, add constraint video_block_has_fields check (type <> 'video' or ( show_title is not null and show_link is not null )); - \ No newline at end of file +