Skip to content

Commit

Permalink
add videos for DAN techniques
Browse files Browse the repository at this point in the history
  • Loading branch information
nknapp committed Aug 23, 2024
1 parent 0aad149 commit de8f0b2
Show file tree
Hide file tree
Showing 16 changed files with 577 additions and 34 deletions.
7 changes: 5 additions & 2 deletions scripts/buildVideoPack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ for (const technique of allTechniques) {
}

const pack: VideoPack = {
name: "Aikido Kompendium",
source: "https://www.aikido-kompendium.de",
metadata: {
name: "Aikido Kompendium",
copyright: "Aikido Dojo Darmstadt",
source: "https://www.aikido-kompendium.de",
},
videos: buildTechniqueTree(allTechniques, (technique) => coerceToArray(technique.metadata.youtube)),
};

Expand Down
24 changes: 22 additions & 2 deletions src/YoutubePlayer/PlayerContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { render } from "solid-js/web";
import { t } from "@/i18n";
import { IconStop } from "@/icons";
import { cls } from "$core/utils/cls.ts";
import type { ResolvedYoutubeLink } from "@/utils/resolveYoutubeLinks.ts";

export async function renderPlayerContainer() {
const container = document.createElement("div");
Expand All @@ -17,6 +18,7 @@ export class PlayerContainerRef extends EventTarget {
constructor(
public htmlElement: HTMLDivElement,
public setVisible: (visible: boolean) => void,
public setVideo: (metadata: ResolvedYoutubeLink) => void,
) {
super();
}
Expand All @@ -27,9 +29,10 @@ const PlayerContainer: Component<{
}> = (props) => {
let playerContainerRef: PlayerContainerRef | null = null;
const [visible, setVisible] = createSignal(false);
const [youtubeLink, setYoutubeLink] = createSignal<ResolvedYoutubeLink | null>(null);

function onPlayerElement(el: HTMLDivElement) {
playerContainerRef = new PlayerContainerRef(el, setVisible);
playerContainerRef = new PlayerContainerRef(el, setVisible, setYoutubeLink);
props.setPlayer(playerContainerRef);
}

Expand All @@ -46,7 +49,24 @@ const PlayerContainer: Component<{
icon={IconStop}
onClick={stop}
/>
<div ref={onPlayerElement} class="absolute inset-0 z-0"></div>
<div ref={onPlayerElement} class="absolute inset-0 z-0 pb-25"></div>

{youtubeLink() != null && (
<div
class={
"absolute bottom-0 left-0 right-0 z-10 bg-secondary-darkest h-24 border-t-4 border-secondary-light flex flex-col text-secondary-light"
}
>
<div class={"h-8 p-1 truncate"}>
{t("video.source")}{" "}
<a href={youtubeLink()?.videoPackMetadata.source}>{youtubeLink()?.videoPackMetadata.name}</a>
</div>
<div class={"h-8 p-1 truncate"} title={youtubeLink()?.title}>
Video: <a href={"https://youtu.be/" + youtubeLink()?.videoId}>{youtubeLink()?.title}</a>
</div>
<div class={"h-8 p-1"}>© {youtubeLink()?.videoPackMetadata.copyright}</div>
</div>
)}
</div>
);
};
15 changes: 8 additions & 7 deletions src/YoutubePlayer/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import type { YoutubeLink } from "$core/model";
import { renderPlayerContainer } from "@/YoutubePlayer/PlayerContainer.tsx";
import { youtubeEnabled } from "$core/store/youtube.ts";
import { loadYoutubeAdapter } from "@/YoutubePlayer/adapter.ts";
import type { ResolvedYoutubeLink } from "@/utils/resolveYoutubeLinks.ts";

export interface YoutubePlayer {
loadVideo(videoId: string, startSeconds?: number, endSeconds?: number): Promise<void>;
loadVideo(video: ResolvedYoutubeLink): Promise<void>;
play(): Promise<void>;
stop(): Promise<void>;
waitForStop(): Promise<void>;
}

export async function playVideo(youtubeLink: YoutubeLink): Promise<void> {
export async function playVideo(youtubeLink: ResolvedYoutubeLink): Promise<void> {
const player = await getOrCreatePlayer();
await player.loadVideo(youtubeLink.videoId, youtubeLink.startSeconds, youtubeLink.endSeconds);
await player.loadVideo(youtubeLink);
await player.play();
await player.waitForStop();
await player.stop();
Expand Down Expand Up @@ -42,9 +42,10 @@ async function createPlayer(): Promise<YoutubePlayer> {
window.addEventListener("resize", updatePlayerSize);
updatePlayerSize();

const result = {
loadVideo(videoId: string, startSeconds?: number, endSeconds?: number) {
return player.loadVideoById(videoId, startSeconds, endSeconds);
const result: YoutubePlayer = {
loadVideo(video: ResolvedYoutubeLink) {
container.setVideo(video);
return player.loadVideoById(video.videoId, video.startSeconds, video.endSeconds);
},
async play() {
await player.playVideo();
Expand Down
4 changes: 2 additions & 2 deletions src/components/solid/atoms/YoutubePlayButton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { type Component, Match, Switch } from "solid-js";
import type { YoutubeLink } from "$core/model";
import { SimpleButton } from "@/components/solid/atoms/SimpleButton.tsx";
import { IconVideoLibrary } from "@/icons";
import { t } from "@/i18n";
import { playVideo } from "@/YoutubePlayer";
import type { ResolvedYoutubeLink } from "@/utils/resolveYoutubeLinks.ts";

export interface YoutubePlayerProps {
link: YoutubeLink;
link: ResolvedYoutubeLink;
type: "button" | "icon";
class?: string;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/solid/organisms/Reader/Reader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type Component, createSignal, For, Suspense } from "solid-js";
import type { DojoInfo } from "$core/model/Dojo.ts";
import { createResource } from "solid-js";
import { createTechniqueStore } from "$core/store";
import { type SpeechPack, type YoutubeLink } from "$core/model";
import { type SpeechPack } from "$core/model";
import { SimpleButton } from "@/components/solid/atoms/SimpleButton.tsx";
import { ExamScroll } from "@/components/solid/organisms/Reader/ExamScroll.tsx";
import { IconAutoMode, IconPlay, IconSkipNext, IconSkipPrevious, IconStop } from "@/icons";
Expand All @@ -14,7 +14,7 @@ import { type DelayControl, DelayIndicator } from "@/components/solid/atoms/Dela
import { youtubeEnabled } from "$core/store/youtube.ts";
import { usePersistentStore } from "@/components/solid/hooks/usePersistentStore.ts";
import { YoutubePlayButton } from "@/components/solid/atoms/YoutubePlayButton.tsx";
import { resolveYoutubeLinks } from "@/utils/resolveYoutubeLinks.ts";
import { type ResolvedYoutubeLink, resolveYoutubeLinks } from "@/utils/resolveYoutubeLinks.ts";

export const Reader: Component<{ dojoInfo: DojoInfo; speechPack: SpeechPack }> = (props) => {
const techniqueStore = createTechniqueStore(props.dojoInfo.id);
Expand Down Expand Up @@ -80,7 +80,7 @@ const Player: Component<{
onClickPrevious(): void;
autoPlayEnabled: boolean;
onClickAutoPlay(): void;
youtube: YoutubeLink[];
youtube: ResolvedYoutubeLink[];
}> = (props) => {
const [speed, setSpeed] = createSignal<Speed>("normal");
const showYoutube = usePersistentStore(youtubeEnabled, false);
Expand Down
4 changes: 2 additions & 2 deletions src/components/solid/organisms/TechniqueChooser/ExamSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const ExamSheet: Component<ExamSheetProps> = (props) => {
}),
);
return (
<div>
<div class={"break-before-page"}>
<ForEntries object={examTable()}>
{(execution, attacks) => (
<div>
Expand All @@ -29,7 +29,7 @@ export const ExamSheet: Component<ExamSheetProps> = (props) => {
{(attack, defences) => (
<div class={"grid grid-cols-3 mt-4 break-inside-avoid"}>
<div>{attack}</div>
<div class={"col-span-2 md:flex flex-wrap"}>
<div class={"col-span-2"}>
<ForEntries object={defences}>
{(defence, directions) => (
<div class={"md:me-6"}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export const VideoPackEditor: Component<{
}> = (props) => {
const [selectedVideo, setSelectedVideo] = createSignal<TechniqueVideo | null>(null);
const [updatedVideos, setUpdatedVideos] = createSignal<Record<string, TechniqueVideo>>(
JSON.parse(localStorage.getItem(`videoPack-${props.videoPack.name}`) ?? "{}"),
JSON.parse(localStorage.getItem(`videoPack-${props.videoPack.metadata.name}`) ?? "{}"),
);

createEffect(() => {
localStorage.setItem(`videoPack-${props.videoPack.name}`, JSON.stringify(updatedVideos()));
localStorage.setItem(`videoPack-${props.videoPack.metadata.name}`, JSON.stringify(updatedVideos()));
});

const resolvedVideos: TechniqueVideo[] = resolveTechniqueTrees([props.videoPack.videos], (technique, videos) => ({
Expand Down Expand Up @@ -57,10 +57,10 @@ export const VideoPackEditor: Component<{

return (
<div>
<h2>{props.videoPack.name}</h2>
<h2>{props.videoPack.metadata.name}</h2>
<p>
<a target="_blank" href={props.videoPack.source}>
{props.videoPack.source}
<a target="_blank" href={props.videoPack.metadata.source}>
{props.videoPack.metadata.source}
</a>
</p>
<div class={"relative flex flex-col gap-2"}>
Expand Down Expand Up @@ -152,11 +152,13 @@ const VideoEditor: Component<{ video: TechniqueVideo; onChange: (video: Techniqu
useKeyboard("KeyS", async () => {
if (player) {
setStart(await player.getCurrentTime());
updateVideo();
}
});
useKeyboard("KeyE", async () => {
if (player) {
setEnd(await player.getCurrentTime());
updateVideo();
}
});

Expand Down
7 changes: 6 additions & 1 deletion src/core/model/VideoPack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import type { TechniqueTree } from "$core/model/TechniqueTree.ts";
import type { YoutubeLink } from "$core/model/TechniqueMetadata.ts";

export interface VideoPack {
metadata: VideoPackMetadata;
videos: TechniqueTree<YoutubeLink[]>;
}

export interface VideoPackMetadata {
name: string;
copyright: string;
source: string;
videos: TechniqueTree<YoutubeLink[]>;
}
1 change: 1 addition & 0 deletions src/core/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from "./Technique";
export * from "./Exam";
export * from "./SpeechPack";
export * from "./TechniqueTree";
export * from "./VideoPack";
7 changes: 5 additions & 2 deletions src/data/videopacks/aikido-kompendium/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { VideoPack } from "$core/model/VideoPack";

export default {
name: "Aikido Kompendium",
source: "https://www.aikido-kompendium.de",
metadata: {
name: "Aikido Kompendium",
copyright: "Aikido Dojo Darmstadt",
source: "https://www.aikido-kompendium.de",
},
videos: {
"suwari waza": {
"ryote dori": {
Expand Down
Loading

0 comments on commit de8f0b2

Please sign in to comment.