Skip to content

Commit

Permalink
feat: next:vtuberページ作成 #149
Browse files Browse the repository at this point in the history
  • Loading branch information
shari-sushi committed Mar 2, 2024
1 parent b81c6d9 commit 2832062
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 3 deletions.
44 changes: 44 additions & 0 deletions t0016Next/myapp/src/components/dropDown/Movie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,47 @@ export const DropDownMovie = ({ posts, selectedVtuber, setSelectedMovie, clearMo
/>
);
};

type DropDownAllMovieProps = {
posts: BasicDataProps;
setSelectedMovie: (value: string) => void;
clearMovieHandler: () => void;
};

export const DropDownAllMovie = ({ posts, setSelectedMovie, clearMovieHandler }: DropDownAllMovieProps) => {
const movies = posts?.vtubers_movies || [{} as ReceivedMovie]
const handleMovieClear = () => {
setSelectedMovie("");
clearMovieHandler();
};

const movieOptions = movies.map((movie: ReceivedMovie) => ({
value: movie.MovieUrl,
label: movie.MovieTitle
}));

return (
<Select
id="selectbox"
instanceId="selectbox"
placeholder="動画タイトルを検索/選択"
className="basic-single"
classNamePrefix="select"
// value={""} //何を入れても選択したものが表示されないだけ
isClearable={true}
isSearchable={true}
name="movie"
blurInputOnSelect={true} //defaultでtrueなら不要。スマホでアクセスしないと確認できないと思う。
captureMenuScroll={true} //スマホ、タブレット用。使ってみてからt/f判断。
styles={DropStyle}
options={movieOptions}
onChange={option => {
if (option) {
setSelectedMovie(option.value);
} else {
handleMovieClear();
}
}}
/>
);
};
17 changes: 17 additions & 0 deletions t0016Next/myapp/src/components/layout/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,20 @@ export function NotLoggedIn() {
</div >
);
}

export function NotFoundVtuber() {
return (
<div className="h-full ">
<h1 className="text-lg pt-1">Vtuberが見つかりません</h1> <br />
<div className="flex flex-col md:flex-none">
<span className="pl-2 pb-4">
Vtuberを登録してみませんか?
</span>
<Link className={`${ToClickTW.regular} justify-center float-right px-3 mr-2 w-24`}
href="/crud/create" >
登録ページ
</Link>
</div>
</div >
);
}
2 changes: 0 additions & 2 deletions t0016Next/myapp/src/pages/user/mypage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ const MyPage = ({ data, isSignin }: Mypage) => {
<YouTubePlayer videoId={currentMovieId} start={start} />
</div>



{vtubers.length + movies.length + karaokes.length === 0 ? (
<div id="feature"
className={`bg-[#657261] rounded top-0 p-1
Expand Down
1 change: 0 additions & 1 deletion t0016Next/myapp/src/pages/user/signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { SigninForm } from "@/components/form/User";
export function SigninPage() {

return (

<Layout pageName={"ログイン"} isSignin={false}>
<div className="flex justify-center w-full mt-6">
<div className="w-full max-w-xs">
Expand Down
182 changes: 182 additions & 0 deletions t0016Next/myapp/src/pages/vtuber/[vtuber_kana].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import React, { useState, useEffect } from 'react';
import https from 'https';
import axios, { AxiosRequestConfig } from 'axios';
import Link from 'next/link';

import { domain } from '@/../env'
import { Layout } from '@/components/layout/Layout'
import { ToClickTW } from '@/styles/tailwiind';
import type { ReceivedKaraoke, ReceivedMovie, ReceivedVtuber } from '@/types/vtuber_content';
import type { ContextType } from '@/types/server'
import { YouTubePlayer } from '@/components/moviePlayer/YoutubePlayer'
import { ConvertStringToTime, ExtractVideoId } from '@/components/Conversion'
import { KaraokePagenatoinTable } from "@/components/table/Karaoke"
import { DropDownAllMovie } from '@/components/dropDown/Movie';
import { NotFoundVtuber } from '@/components/layout/Main';
import { useRouter } from 'next/router';
import { GetServerSidePropsContext } from 'next';

type VtuberPage = {
posts: {
vtubers: ReceivedVtuber[];
vtubers_movies: ReceivedMovie[];
vtubers_movies_karaokes: ReceivedKaraoke[];
};
isSignin: boolean;
}

export default function SingsPage({ posts, isSignin }: VtuberPage) {
const movies = posts?.vtubers_movies || [] as ReceivedMovie[];
const karaokes = posts?.vtubers_movies_karaokes || [] as ReceivedKaraoke[];

// ようつべ用
const primaryYoutubeUrl = "kORHSmXcYNc" //船長 
const primaryYoutubeStartTime = ConvertStringToTime("00:08:29")
const [currentMovieId, setCurrentMovieId] = useState<string>(primaryYoutubeUrl);
const [start, setStart] = useState<number>(primaryYoutubeStartTime)
const handleMovieClickYouTube = (url: string, start: number) => {
setCurrentMovieId(ExtractVideoId(url));
setStart(start);
}

const [selectedPost, setSelectedPost] = useState<ReceivedKaraoke>({} as ReceivedKaraoke)

const [selectedVtuber, setSelectedVtuber] = useState<number>(0);
const [selectedMovie, setSelectedMovie] = useState<string>("");
const [filteredKaraokes, setFilteredKarakes] = useState<ReceivedKaraoke[]>([]);
const clearMovieHandler = () => {
};

useEffect(() => {
const filterdkaraokes = FilterKaraokesByUrl(karaokes, selectedMovie)
setFilteredKarakes(filterdkaraokes)
}, [selectedVtuber, selectedMovie]);

if (karaokes.length == 0) {
return (
<Layout pageName={`Vtuber特設ページ`} isSignin={isSignin}>
<div className='flex flex-col w-full max-w-[1000px] mx-auto'>
<div className={`pt-6 flex flex-col items-center`}>
<div className={`flex`}>
<div id="feature"
className={`flex flex-col md:flex-row bg-[#657261] rounded
max-w-[1000px] md:h-[265px] h-full w-full mx-auto
top-0 p-1 `
}
>
{/* 左側の要素 */}
<div className='flex flex-col mr-1 '>
<div className='relative flex justify-center'>
<YouTubePlayer videoId={currentMovieId} start={start} />
</div>
</div>

{/* 右側の要素 */}
<div id="right" className={`relative px-1 rounded border`}>
<NotFoundVtuber />
</div>
</div>
</div>
</div>
</div>
</Layout>
)
}

return (
<Layout pageName={`Vtuber特設ページ`} isSignin={isSignin}>
<div className='flex flex-col w-full max-w-[1000px] mx-auto'>
<div className={`pt-6 flex flex-col items-center`}>
<div className={`flex`}>
<div id="feature"
className={`flex flex-col md:flex-row bg-[#657261] rounded
max-w-[1000px] md:h-[265px] h-full w-full mx-auto
top-0 p-1
`}
>
{/* 左側の要素 */}
<div className='flex flex-col mr-1 '>
<div className='relative flex justify-center'>
<YouTubePlayer videoId={currentMovieId} start={start} />
</div>
</div>

{/* 右側の要素 */}
<div id="right" className={`relative px-1 rounded border`}>
<div className='flex py-3 text-black bg-[#FFF6E4] justify-center rounded-xl'>
<span className='text-xl font-bold mr-2'> {karaokes?.[0].VtuberName}</span>
<span className='mt-1'>の歌枠</span>
</div>
<span >動画絞込み(入力できます)</span>
<DropDownAllMovie
posts={posts}
setSelectedMovie={setSelectedMovie}
clearMovieHandler={clearMovieHandler}
/>
<div className='pt-5'>
<span>お探しの歌枠や歌がありませんか?</span> <br />
<Link className={`${ToClickTW.regular} justify-center float-right px-3 mr-2`}
href="/crud/create" >データを登録する</Link>
</div>
</div>
</div>
</div>
</div>
<div className="flex flex-col w-full">
<KaraokePagenatoinTable
posts={filteredKaraokes}
handleMovieClickYouTube={handleMovieClickYouTube}
setSelectedPost={setSelectedPost}
/>
</div>
</div>
</Layout>
)
}

const FilterKaraokesByUrl = (karaokes: ReceivedKaraoke[], selectedMovie: string) => {
if (selectedMovie == "") {
return karaokes
} else {
const choiceKaraoke = karaokes.filter((karaokes: ReceivedKaraoke) => karaokes.MovieUrl === selectedMovie);
return choiceKaraoke
}
}

/////////////////////////////////////////////////////////////////////////////
export async function getServerSideProps(context: GetServerSidePropsContext) {
const kana = context.query.vtuber_kana;;

const rawCookie = context.req.headers.cookie;
const sessionToken = rawCookie?.split(';').find((cookie: string) => cookie.trim().startsWith('auth-token='))?.split('=')[1];
console.log("sessionToken", sessionToken)
let isSignin = false
if (sessionToken) {
isSignin = true
}
// サーバーの証明書が認証されない自己証明書でもHTTPSリクエストを継続する
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
const options: AxiosRequestConfig = {
headers: {
'Cache-Control': 'no-store', //cache(キャッシュ)を無効にする様だが、必要性理解してない
cookie: `auth-token=${sessionToken}`,
},
withCredentials: true, //HttpヘッダーにCookieを含める
httpsAgent: process.env.NODE_ENV === "production" ? undefined : httpsAgent
};

let resData = null;
try {
const res = await axios.get(`${domain.backendHost}/vcontents/vtuber/${kana}`, options);
resData = res.data;
} catch (error) {
console.log("erroe in axios.get:", error);
}
return {
props: {
posts: resData,
isSignin: isSignin,
}
}
}

0 comments on commit 2832062

Please sign in to comment.