diff --git a/src/Component/Comments/Comments.tsx b/src/Component/Comments/Comments.tsx
index a511a48..e863014 100644
--- a/src/Component/Comments/Comments.tsx
+++ b/src/Component/Comments/Comments.tsx
@@ -2,7 +2,7 @@ import "./_comments.scss"
import {Comment} from "../Comment/Comment.tsx";
import {Form} from "react-bootstrap";
import {useAppDispatch , useAppSelector} from "../../redux/store.ts";
-import {useEffect , useState} from "react";
+import {FormEvent , useEffect , useState} from "react";
import {GetCommentsThunk , postCommentsThunk} from "../../redux/commentSlice.ts";
@@ -33,7 +33,7 @@ export function Comments({videoId, totalComments} : CommentsProps){
(comment) => comment.snippet.topLevelComment.snippet
)
- function handleSubmit(e){
+ function handleSubmit(e : FormEvent){
e.preventDefault()
setCommentText(commentText)
if(commentText.length == 0) return
diff --git a/src/Component/Header/header.tsx b/src/Component/Header/header.tsx
index 7664b77..70a8cef 100644
--- a/src/Component/Header/header.tsx
+++ b/src/Component/Header/header.tsx
@@ -4,11 +4,15 @@ import {AiOutlineSearch} from "react-icons/ai";
import {MdApps , MdNotifications} from "react-icons/md";
import ytLogo from "../../public/Youtube_logo.png"
import "./_header.scss"
-import { useState} from "react";
+import {FormEvent , useState} from "react";
import {useNavigate} from "react-router-dom";
import { useAppSelector} from "../../redux/store.ts";
-export function Header({handleToggleSidebar}){
+type HeaderProps = {
+ handleToggleSidebar : () => void
+}
+
+export function Header({handleToggleSidebar} : HeaderProps){
const [input, setInput] = useState("")
const navigate= useNavigate()
@@ -16,7 +20,7 @@ export function Header({handleToggleSidebar}){
const { user } = useAppSelector(state => state.auth)
- function handleSubmit(e){
+ function handleSubmit(e : FormEvent){
e.preventDefault()
setInput(input)
if(input.trim() !== "") navigate(`search/${input}`)
diff --git a/src/Component/Sidebar/sidebar.tsx b/src/Component/Sidebar/sidebar.tsx
index 093ca7a..cf427ff 100644
--- a/src/Component/Sidebar/sidebar.tsx
+++ b/src/Component/Sidebar/sidebar.tsx
@@ -31,7 +31,7 @@ import {getsubscriptionsThunk} from "../../redux/subscriptionsSlice.ts";
const cache = new Map();
-export function Sidebar({showSidebar}){
+export function Sidebar({showSidebar} : {showSidebar : boolean}){
if (window.scrollY) {
window.scroll(0, 0); // reset the scroll position to the top left of the document.
@@ -57,7 +57,7 @@ export function Sidebar({showSidebar}){
const { subscriptions } = useAppSelector(state => state.subscriptions)
- function handleClick(channelId){
+ function handleClick(channelId : string){
navigate(`/feed/${channelId}`)
}
diff --git a/src/Component/Video/video.tsx b/src/Component/Video/video.tsx
index 38f4dda..5db8d4b 100644
--- a/src/Component/Video/video.tsx
+++ b/src/Component/Video/video.tsx
@@ -5,7 +5,14 @@ import moment from 'moment'
import numeral from 'numeral'
import { useNavigate} from "react-router-dom";
-export function Video({item, channelScreen, duration, channelIcon}){
+type videoProps = {
+ item : any,
+ channelScreen? : any,
+ duration : any,
+ channelIcon : any
+}
+
+export function Video({item, channelScreen, duration, channelIcon} : videoProps){
const {
id,
@@ -89,7 +96,7 @@ export function Video({item, channelScreen, duration, channelIcon}){
{!channelScreen && (
{/*
*/}
-
+
{channelTitle}
diff --git a/src/Component/VideoHorizontal/VideoHorizontal.tsx b/src/Component/VideoHorizontal/VideoHorizontal.tsx
index e0ee460..a1f4c77 100644
--- a/src/Component/VideoHorizontal/VideoHorizontal.tsx
+++ b/src/Component/VideoHorizontal/VideoHorizontal.tsx
@@ -4,7 +4,15 @@ import moment from "moment";
import numeral from "numeral";
import { useNavigate} from "react-router-dom";
-export function VideoHorizontal({videos, searchScreen, searchresult, subScreen, channelIcons, viewsDuration}){
+type VideoHorizontalProps = {
+ videos : any,
+ searchScreen? : any,
+ searchresult? : boolean,
+ subScreen? : any,
+ channelIcon? : any,
+ viewsDuration : any
+}
+export function VideoHorizontal({videos, searchScreen, searchresult, subScreen, channelIcon, viewsDuration} : VideoHorizontalProps){
// const [views, setViews] = useState()
// const [duration, setDuration] = useState()
@@ -127,14 +135,14 @@ export function VideoHorizontal({videos, searchScreen, searchresult, subScreen,
{subScreen &&
- {channelIcons?.snippet?.customUrl} . {' '}
- {numeral ( channelIcons?.statistics?.subscriberCount ).format ( '0.a' )} Subscribers
+ {channelIcon?.snippet?.customUrl} . {' '}
+ {numeral ( channelIcon?.statistics?.subscriberCount ).format ( '0.a' )} Subscribers
}
{isVideo && searchresult &&
-
+
}
{ isVideo && searchresult &&
{ channelTitle }
}
diff --git a/src/Component/VideoMetaData/VideoMetaData.tsx b/src/Component/VideoMetaData/VideoMetaData.tsx
index add091a..973e6d9 100644
--- a/src/Component/VideoMetaData/VideoMetaData.tsx
+++ b/src/Component/VideoMetaData/VideoMetaData.tsx
@@ -14,7 +14,7 @@ type videoMetadataProps = {
videoID : string |undefined
}
-export function VideoMetaData({video ,videoID} : videoMetadataProps) {
+export function VideoMetaData({video } : videoMetadataProps) {
const dispatch = useAppDispatch()
diff --git a/src/Data/SampelData.ts b/src/Data/SampelData.ts
index ff2b5c5..bc879c5 100644
--- a/src/Data/SampelData.ts
+++ b/src/Data/SampelData.ts
@@ -1,308 +1,308 @@
-// Sample JSON for /videos endpoint, paginated with 20 items
-
-const videoItem = [
- {
- "kind": "youtube#video",
- "etag": "etag_value",
- "id": "video_id_1",
- "snippet": {
- "publishedAt": "2023-09-29T00:00:00Z",
- "channelId": "channel_id_1",
- "title": "Video Title 1",
- "description": "Video description 1",
- "thumbnails": {
- "default": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 120,
- "height": 90
- },
- "medium": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 320,
- "height": 180
- },
- "high": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 480,
- "height": 360
- }
- },
- "channelTitle": "Channel Title 1",
- "tags": ["tag1", "tag2"],
- "categoryId": "22",
- "liveBroadcastContent": "none",
- "localized": {
- "title": "Localized Title 1",
- "description": "Localized description 1"
- }
- },
- "contentDetails": {
- "duration": "PT10M34S",
- "dimension": "2d",
- "definition": "hd",
- "caption": "false",
- "licensedContent": true,
- "projection": "rectangular"
- },
- "statistics": {
- "viewCount": "123456",
- "likeCount": "4567",
- "dislikeCount": "123",
- "favoriteCount": "0",
- "commentCount": "89"
- }
- }
-]
-const repeat = (arr, n) => [].concat(...Array(n).fill(arr));
-
-export const videosResponse = {
- "kind": "youtube#videoListResponse",
- "etag": "etag_value",
- "nextPageToken": "CAUQAA",
- "prevPageToken": (Math.random() * 10000).toString(),
- "pageInfo": {
- "totalResults": 200,
- "resultsPerPage": 20
- },
- "items": repeat(videoItem, 20)
-};
-
-
-
-// Sample JSON for /search by keyword endpoint
-export const searchResponse = {
- "kind": "youtube#searchListResponse",
- "etag": "etag_value",
- "nextPageToken": "CAoQAA",
- "prevPageToken": "CAAQAA",
- "regionCode": "US",
- "pageInfo": {
- "totalResults": 1000000,
- "resultsPerPage": 20
- },
- "items": [
- {
- "kind": "youtube#searchResult",
- "etag": "etag_value",
- "id": {
- "kind": "youtube#video",
- "videoId": "video_id_1"
- },
- "snippet": {
- "publishedAt": "2023-09-29T00:00:00Z",
- "channelId": "channel_id_1",
- "title": "Search Result Video Title 1",
- "description": "Search result video description 1",
- "thumbnails": {
- "default": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 120,
- "height": 90
- },
- "medium": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 320,
- "height": 180
- },
- "high": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 480,
- "height": 360
- }
- },
- "channelTitle": "Search Result Channel Title 1",
- "liveBroadcastContent": "none",
- "publishTime": "2023-09-29T00:00:00Z"
- }
- },
- {
- "kind": "youtube#searchResult",
- "etag": "etag_value",
- "id": {
- "kind": "youtube#video",
- "videoId": "video_id_2"
- },
- "snippet": {
- "publishedAt": "2023-09-28T00:00:00Z",
- "channelId": "channel_id_2",
- "title": "Search Result Video Title 2",
- "description": "Search result video description 2",
- "thumbnails": {
- "default": {
- "url": "https://example.com/thumbnail2.jpg",
- "width": 120,
- "height": 90
- },
- "medium": {
- "url": "https://example.com/thumbnail2.jpg",
- "width": 320,
- "height": 180
- },
- "high": {
- "url": "https://example.com/thumbnail2.jpg",
- "width": 480,
- "height": 360
- }
- },
- "channelTitle": "Search Result Channel Title 2",
- "liveBroadcastContent": "none",
- "publishTime": "2023-09-28T00:00:00Z"
- }
- }
- // ...more items (20 items total)
- ]
-};
-
-export const commentThreadsResponse = {
- "kind": "youtube#commentThreadListResponse",
- "etag": "etag_value",
- "nextPageToken": "CAEQAA",
- "pageInfo": {
- "totalResults": 100,
- "resultsPerPage": 20
- },
- "items": repeat([
- {
- "kind": "youtube#commentThread",
- "etag": "etag_value",
- "id": "comment_thread_id_1",
- "snippet": {
- "videoId": "video_id_1",
- "topLevelComment": {
- "kind": "youtube#comment",
- "etag": "etag_value",
- "id": "comment_id_1",
- "snippet": {
- "authorDisplayName": "User 1",
- "authorProfileImageUrl": "https://example.com/profile1.jpg",
- "authorChannelUrl": "https://www.youtube.com/channel/channel_id_1",
- "authorChannelId": {
- "value": "channel_id_1"
- },
- "textOriginal": "This is a sample top-level comment 1",
- "textDisplay": "This is a sample top-level comment 1",
- "likeCount": 10,
- "publishedAt": "2023-09-29T00:00:00Z",
- "updatedAt": "2023-09-29T00:00:00Z"
- }
- },
- "canReply": true,
- "totalReplyCount": 5,
- "isPublic": true
- },
- "replies": {
- "comments": [
- {
- "kind": "youtube#comment",
- "etag": "etag_value",
- "id": "reply_id_1",
- "snippet": {
- "authorDisplayName": "User 2",
- "authorProfileImageUrl": "https://example.com/profile2.jpg",
- "authorChannelUrl": "https://www.youtube.com/channel/channel_id_2",
- "authorChannelId": {
- "value": "channel_id_2"
- },
- "textOriginal": "This is a sample reply 1",
- "textDisplay": "This is a sample reply 1",
- "likeCount": 3,
- "publishedAt": "2023-09-29T01:00:00Z",
- "updatedAt": "2023-09-29T01:00:00Z"
- }
- }
- ]
- }
- }
- ], 20)
-};
-
-// Sample JSON for /subscriptions endpoint
-export const subscriptionsResponse = {
- "kind": "youtube#subscriptionListResponse",
- "etag": "etag_value",
- "nextPageToken": "CAoQAA",
- "pageInfo": {
- "totalResults": 100,
- "resultsPerPage": 20
- },
- "items": repeat([
- {
- "kind": "youtube#subscription",
- "etag": "etag_value",
- "id": "subscription_id_1",
- "snippet": {
- "publishedAt": "2023-09-29T00:00:00Z",
- "title": "Sample Channel 1",
- "description": "This is a sample subscription",
- "resourceId": {
- "kind": "youtube#channel",
- "channelId": "channel_id_1"
- },
- "thumbnails": {
- "default": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 88,
- "height": 88
- },
- "medium": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 240,
- "height": 240
- },
- "high": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 800,
- "height": 800
- }
- },
- "channelTitle": "Sample Channel Title 1"
- }
- }
- ], 20)
-};
-
-// Sample JSON for /channel by ID endpoint
-export const channelByIdResponse = {
- "kind": "youtube#channelListResponse",
- "etag": "etag_value",
- "pageInfo": {
- "totalResults": 1,
- "resultsPerPage": 1
- },
- "items": repeat([
- {
- "kind": "youtube#channel",
- "etag": "etag_value",
- "id": "channel_id_1",
- "snippet": {
- "title": "Sample Channel Title 1",
- "description": "This is a sample channel description",
- "publishedAt": "2010-06-09T00:00:00Z",
- "thumbnails": {
- "default": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 88,
- "height": 88
- },
- "medium": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 240,
- "height": 240
- },
- "high": {
- "url": "https://example.com/thumbnail1.jpg",
- "width": 800,
- "height": 800
- }
- },
- "country": "US"
- },
- "statistics": {
- "viewCount": "12345678",
- "subscriberCount": "1000000",
- "hiddenSubscriberCount": false,
- "videoCount": "500"
- }
- }
- ], 1)
-};
\ No newline at end of file
+// // Sample JSON for /videos endpoint, paginated with 20 items
+//
+// const videoItem = [
+// {
+// "kind": "youtube#video",
+// "etag": "etag_value",
+// "id": "video_id_1",
+// "snippet": {
+// "publishedAt": "2023-09-29T00:00:00Z",
+// "channelId": "channel_id_1",
+// "title": "Video Title 1",
+// "description": "Video description 1",
+// "thumbnails": {
+// "default": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 120,
+// "height": 90
+// },
+// "medium": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 320,
+// "height": 180
+// },
+// "high": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 480,
+// "height": 360
+// }
+// },
+// "channelTitle": "Channel Title 1",
+// "tags": ["tag1", "tag2"],
+// "categoryId": "22",
+// "liveBroadcastContent": "none",
+// "localized": {
+// "title": "Localized Title 1",
+// "description": "Localized description 1"
+// }
+// },
+// "contentDetails": {
+// "duration": "PT10M34S",
+// "dimension": "2d",
+// "definition": "hd",
+// "caption": "false",
+// "licensedContent": true,
+// "projection": "rectangular"
+// },
+// "statistics": {
+// "viewCount": "123456",
+// "likeCount": "4567",
+// "dislikeCount": "123",
+// "favoriteCount": "0",
+// "commentCount": "89"
+// }
+// }
+// ]
+// const repeat = (arr , n) => [].concat(...Array(n).fill(arr));
+//
+// export const videosResponse = {
+// "kind": "youtube#videoListResponse",
+// "etag": "etag_value",
+// "nextPageToken": "CAUQAA",
+// "prevPageToken": (Math.random() * 10000).toString(),
+// "pageInfo": {
+// "totalResults": 200,
+// "resultsPerPage": 20
+// },
+// "items": repeat(videoItem, 20)
+// };
+//
+//
+//
+// // Sample JSON for /search by keyword endpoint
+// export const searchResponse = {
+// "kind": "youtube#searchListResponse",
+// "etag": "etag_value",
+// "nextPageToken": "CAoQAA",
+// "prevPageToken": "CAAQAA",
+// "regionCode": "US",
+// "pageInfo": {
+// "totalResults": 1000000,
+// "resultsPerPage": 20
+// },
+// "items": [
+// {
+// "kind": "youtube#searchResult",
+// "etag": "etag_value",
+// "id": {
+// "kind": "youtube#video",
+// "videoId": "video_id_1"
+// },
+// "snippet": {
+// "publishedAt": "2023-09-29T00:00:00Z",
+// "channelId": "channel_id_1",
+// "title": "Search Result Video Title 1",
+// "description": "Search result video description 1",
+// "thumbnails": {
+// "default": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 120,
+// "height": 90
+// },
+// "medium": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 320,
+// "height": 180
+// },
+// "high": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 480,
+// "height": 360
+// }
+// },
+// "channelTitle": "Search Result Channel Title 1",
+// "liveBroadcastContent": "none",
+// "publishTime": "2023-09-29T00:00:00Z"
+// }
+// },
+// {
+// "kind": "youtube#searchResult",
+// "etag": "etag_value",
+// "id": {
+// "kind": "youtube#video",
+// "videoId": "video_id_2"
+// },
+// "snippet": {
+// "publishedAt": "2023-09-28T00:00:00Z",
+// "channelId": "channel_id_2",
+// "title": "Search Result Video Title 2",
+// "description": "Search result video description 2",
+// "thumbnails": {
+// "default": {
+// "url": "https://example.com/thumbnail2.jpg",
+// "width": 120,
+// "height": 90
+// },
+// "medium": {
+// "url": "https://example.com/thumbnail2.jpg",
+// "width": 320,
+// "height": 180
+// },
+// "high": {
+// "url": "https://example.com/thumbnail2.jpg",
+// "width": 480,
+// "height": 360
+// }
+// },
+// "channelTitle": "Search Result Channel Title 2",
+// "liveBroadcastContent": "none",
+// "publishTime": "2023-09-28T00:00:00Z"
+// }
+// }
+// // ...more items (20 items total)
+// ]
+// };
+//
+// export const commentThreadsResponse = {
+// "kind": "youtube#commentThreadListResponse",
+// "etag": "etag_value",
+// "nextPageToken": "CAEQAA",
+// "pageInfo": {
+// "totalResults": 100,
+// "resultsPerPage": 20
+// },
+// "items": repeat([
+// {
+// "kind": "youtube#commentThread",
+// "etag": "etag_value",
+// "id": "comment_thread_id_1",
+// "snippet": {
+// "videoId": "video_id_1",
+// "topLevelComment": {
+// "kind": "youtube#comment",
+// "etag": "etag_value",
+// "id": "comment_id_1",
+// "snippet": {
+// "authorDisplayName": "User 1",
+// "authorProfileImageUrl": "https://example.com/profile1.jpg",
+// "authorChannelUrl": "https://www.youtube.com/channel/channel_id_1",
+// "authorChannelId": {
+// "value": "channel_id_1"
+// },
+// "textOriginal": "This is a sample top-level comment 1",
+// "textDisplay": "This is a sample top-level comment 1",
+// "likeCount": 10,
+// "publishedAt": "2023-09-29T00:00:00Z",
+// "updatedAt": "2023-09-29T00:00:00Z"
+// }
+// },
+// "canReply": true,
+// "totalReplyCount": 5,
+// "isPublic": true
+// },
+// "replies": {
+// "comments": [
+// {
+// "kind": "youtube#comment",
+// "etag": "etag_value",
+// "id": "reply_id_1",
+// "snippet": {
+// "authorDisplayName": "User 2",
+// "authorProfileImageUrl": "https://example.com/profile2.jpg",
+// "authorChannelUrl": "https://www.youtube.com/channel/channel_id_2",
+// "authorChannelId": {
+// "value": "channel_id_2"
+// },
+// "textOriginal": "This is a sample reply 1",
+// "textDisplay": "This is a sample reply 1",
+// "likeCount": 3,
+// "publishedAt": "2023-09-29T01:00:00Z",
+// "updatedAt": "2023-09-29T01:00:00Z"
+// }
+// }
+// ]
+// }
+// }
+// ], 20)
+// };
+//
+// // Sample JSON for /subscriptions endpoint
+// export const subscriptionsResponse = {
+// "kind": "youtube#subscriptionListResponse",
+// "etag": "etag_value",
+// "nextPageToken": "CAoQAA",
+// "pageInfo": {
+// "totalResults": 100,
+// "resultsPerPage": 20
+// },
+// "items": repeat([
+// {
+// "kind": "youtube#subscription",
+// "etag": "etag_value",
+// "id": "subscription_id_1",
+// "snippet": {
+// "publishedAt": "2023-09-29T00:00:00Z",
+// "title": "Sample Channel 1",
+// "description": "This is a sample subscription",
+// "resourceId": {
+// "kind": "youtube#channel",
+// "channelId": "channel_id_1"
+// },
+// "thumbnails": {
+// "default": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 88,
+// "height": 88
+// },
+// "medium": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 240,
+// "height": 240
+// },
+// "high": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 800,
+// "height": 800
+// }
+// },
+// "channelTitle": "Sample Channel Title 1"
+// }
+// }
+// ], 20)
+// };
+//
+// // Sample JSON for /channel by ID endpoint
+// export const channelByIdResponse = {
+// "kind": "youtube#channelListResponse",
+// "etag": "etag_value",
+// "pageInfo": {
+// "totalResults": 1,
+// "resultsPerPage": 1
+// },
+// "items": repeat([
+// {
+// "kind": "youtube#channel",
+// "etag": "etag_value",
+// "id": "channel_id_1",
+// "snippet": {
+// "title": "Sample Channel Title 1",
+// "description": "This is a sample channel description",
+// "publishedAt": "2010-06-09T00:00:00Z",
+// "thumbnails": {
+// "default": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 88,
+// "height": 88
+// },
+// "medium": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 240,
+// "height": 240
+// },
+// "high": {
+// "url": "https://example.com/thumbnail1.jpg",
+// "width": 800,
+// "height": 800
+// }
+// },
+// "country": "US"
+// },
+// "statistics": {
+// "viewCount": "12345678",
+// "subscriberCount": "1000000",
+// "hiddenSubscriberCount": false,
+// "videoCount": "500"
+// }
+// }
+// ], 1)
+// };
\ No newline at end of file
diff --git a/src/Data/fetchApi.ts b/src/Data/fetchApi.ts
index 3c819a6..b5bff0f 100644
--- a/src/Data/fetchApi.ts
+++ b/src/Data/fetchApi.ts
@@ -7,7 +7,7 @@ export const FetchApi = axios.create({
}
})
-export async function getyoutubeVideos(getState){
+export async function getyoutubeVideos(getState : () => any){
try {
const res = await FetchApi("/videos",{
params : {
@@ -26,7 +26,7 @@ export async function getyoutubeVideos(getState){
}
}
-export async function getVideosByKeyword( keyword : string, getState ){
+export async function getVideosByKeyword( keyword : string, getState : () => any ){
try {
const res = await FetchApi("/search",{
params : {
@@ -45,7 +45,7 @@ export async function getVideosByKeyword( keyword : string, getState ){
}
}
-export async function getsubscriptions(getState){
+export async function getsubscriptions(getState : () => any){
try {
const res = await FetchApi("/subscriptions",{
params : {
@@ -130,7 +130,7 @@ export async function GetComments(id : string | undefined ){
}
}
-export async function postComments(text : string, getState ,id : string, ){
+export async function postComments(text : string, getState : () => any ,id : string, ){
const obj = {
"snippet" : {
@@ -177,7 +177,7 @@ export async function channelBYID(id : string | undefined){
}
}
-export async function SubStat(channelID : string, getState){
+export async function SubStat(channelID : string, getState : () => any){
try {
const res = await FetchApi("/subscriptions",{
params : {
@@ -229,7 +229,7 @@ export async function getVideosByChannel(uploadPlaylistId : string | undefined){
}
}
-export async function getDurationView(videoIds : string){
+export async function getDurationView(videoIds : string[] | string){
try {
const res = await FetchApi('/videos',{
params:{
diff --git a/src/Page/Home.tsx b/src/Page/Home.tsx
index e30eccf..7680719 100644
--- a/src/Page/Home.tsx
+++ b/src/Page/Home.tsx
@@ -1,15 +1,15 @@
import {Header} from "../Component/Header/header.tsx";
import {Sidebar} from "../Component/Sidebar/sidebar.tsx";
import {Container} from "react-bootstrap";
-import { useState} from "react";
-import {useAppSelector} from "../redux/store.ts";
-import {useNavigate} from "react-router-dom";
+import {ReactNode , useState} from "react";
+// import {useAppSelector} from "../redux/store.ts";
+// import {useNavigate} from "react-router-dom";
-export function Home({children}){
+export function Home({children} : {children : ReactNode}){
const [showSidebar, toggleSidebar] = useState(false)
- const { loading,accessToken, user, error} = useAppSelector((state) => state.auth)
- const navigate = useNavigate()
+ // const { loading,accessToken, user, error} = useAppSelector((state) => state.auth)
+ // const navigate = useNavigate()
const handleToggleSidebar = () => {
toggleSidebar(value => !value)
diff --git a/src/Screen/Homescreen.tsx b/src/Screen/Homescreen.tsx
index 103d924..5f92d31 100644
--- a/src/Screen/Homescreen.tsx
+++ b/src/Screen/Homescreen.tsx
@@ -1,7 +1,7 @@
import {Col , Container} from "react-bootstrap";
import {CategoryBar} from "../Component/Category/CategoryBar.tsx";
import {Video} from "../Component/Video/video.tsx";
-import {useEffect , useState} from "react";
+import {useEffect } from "react";
import {useAppDispatch , useAppSelector} from "../redux/store.ts";
// import {getVideosByKeyword , getyoutubeVideos} from "../redux/videoSlice.ts";
import InfiniteScroll from "react-infinite-scroll-component";
@@ -46,7 +46,7 @@ export function HomeScreen() {
activeCategory ,
loading ,
nextPageToken ,
- videoIds ,
+ // videoIds ,
duration ,
channelIcon
} = useAppSelector ( (state) => state.homeVideos )
@@ -54,8 +54,8 @@ export function HomeScreen() {
const category = sessionStorage.getItem ( "keyword" )
// const[homeVideos, setHomeVideos] = useState([])
- const [allVideoIDs , setAllVideoIDs] = useState ( [] )
- const [icons , setIcons] = useState ( [] )
+ // const [allVideoIDs , setAllVideoIDs] = useState ( [] )
+ // const [icons , setIcons] = useState ( [] )
useEffect ( () => {
@@ -71,6 +71,8 @@ export function HomeScreen() {
// getyoutubeVideos().then(()=>{})
} else {
+ if(!category) return
+
console.log ( JSON.parse ( category ) )
dispatch ( getVideosByKeywordThunk ( { keyword : JSON.parse ( category ) } ) )
@@ -117,7 +119,7 @@ export function HomeScreen() {
videos.map ( (item , index) => (
) ) :
diff --git a/src/Screen/LoginScreen/LoginScreen.tsx b/src/Screen/LoginScreen/LoginScreen.tsx
index 98e0671..1782603 100644
--- a/src/Screen/LoginScreen/LoginScreen.tsx
+++ b/src/Screen/LoginScreen/LoginScreen.tsx
@@ -1,7 +1,6 @@
import "./_loginScreen.scss"
import {useAppDispatch , useAppSelector} from "../../redux/store.ts";
import {login} from "../../redux/authSlice.ts";
-import {Simulate} from "react-dom/test-utils";
import {useNavigate} from "react-router-dom";
import {useEffect} from "react";
@@ -10,7 +9,7 @@ export function LoginScreen() {
const dispatch = useAppDispatch ()
- const { loading , accessToken , user , error } = useAppSelector ( (state) => state.auth )
+ const { accessToken } = useAppSelector ( (state) => state.auth )
const navigate = useNavigate ()
function handleClick() {
@@ -25,13 +24,13 @@ export function LoginScreen() {
return (
-
Youtube Clone
+
Video streaming and viewing platform
-
This Project is made using YOUTUBE DATA API
+ {/*
This Project is made using YOUTUBE DATA API
*/}
)
diff --git a/src/Screen/SearchScreen/SearchScreen.tsx b/src/Screen/SearchScreen/SearchScreen.tsx
index 70f63d3..05ffb05 100644
--- a/src/Screen/SearchScreen/SearchScreen.tsx
+++ b/src/Screen/SearchScreen/SearchScreen.tsx
@@ -1,4 +1,4 @@
-import React , {useEffect , useState} from 'react';
+import {useEffect , useState} from 'react';
import {useParams} from "react-router-dom";
import {useAppDispatch , useAppSelector} from "../../redux/store.ts";
// import {searchVideosByKeyword} from "../../redux/searchVideoSlice.ts";
@@ -17,6 +17,9 @@ export function SearchScreen() {
console.log ( "query" , query )
useEffect ( () => {
+
+ if(!query) return
+
dispatch ( searchVideosByKeywordThunk ( { keyword : query } ) )
// searchVideosByKeyword( {keyword : query }).then(()=>{})
@@ -39,7 +42,7 @@ export function SearchScreen() {
/>
) )
) : (
-
+
) }
diff --git a/src/Screen/Subscription/Subscription.tsx b/src/Screen/Subscription/Subscription.tsx
index c2b5e15..9b141b6 100644
--- a/src/Screen/Subscription/Subscription.tsx
+++ b/src/Screen/Subscription/Subscription.tsx
@@ -24,11 +24,11 @@ export function Subscription() {
All subscriptions
{ !loading ? (
subscriptions?.map ( (video , index) => (
-
) )
) : (
-
+
) }
diff --git a/src/Screen/WatchScreen/WatchScreen.tsx b/src/Screen/WatchScreen/WatchScreen.tsx
index 209ce64..566aba6 100644
--- a/src/Screen/WatchScreen/WatchScreen.tsx
+++ b/src/Screen/WatchScreen/WatchScreen.tsx
@@ -19,6 +19,8 @@ export function WatchScreen() {
const dispatch = useAppDispatch()
useEffect ( () => {
+ if(!id) return
+
dispatch(getVideosByIdThunk({id : id}))
dispatch(getReletedVideosTHunk({id : id}))
@@ -29,7 +31,7 @@ export function WatchScreen() {
const { videos, loading } = useAppSelector(state => state.selectVideo)
- const { relatedVideos, loading : relatedVideoLoading, ViewsDuration , channelIcons } = useAppSelector(state => state.relatedVideo)
+ const { relatedVideos, ViewsDuration , channelIcons } = useAppSelector(state => state.relatedVideo)
// const {comments} = useAppSelector(state => state.comment)
@@ -53,12 +55,12 @@ export function WatchScreen() {
-
+
{!loading ?
relatedVideos?.map ( (video, index) => (
-
+
)
) :
diff --git a/src/Screen/channelScreen/channelScreen.tsx b/src/Screen/channelScreen/channelScreen.tsx
index f226c42..219967e 100644
--- a/src/Screen/channelScreen/channelScreen.tsx
+++ b/src/Screen/channelScreen/channelScreen.tsx
@@ -1,4 +1,4 @@
-import React , {useEffect} from 'react';
+import {useEffect} from 'react';
import {useParams} from "react-router-dom";
import {useAppDispatch , useAppSelector} from "../../redux/store.ts";
// import {channelBYID , getVideosByChannel , SubStat} from "../../redux/channelSclice.ts";
@@ -16,6 +16,8 @@ export function ChannelScreen() {
useEffect ( () => {
+ if (!channelId) return
+
dispatch ( getVideosByChannelThunk ( { id : channelId } ) )
dispatch ( channelBYIDThunk ( { id : channelId } ) )
@@ -62,7 +64,7 @@ export function ChannelScreen() {
: [...Array ( 15 )].map ( () => (
diff --git a/src/main.tsx b/src/main.tsx
index 23b0aad..9f61c25 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,4 +1,3 @@
-import {StrictMode} from 'react'
import {createRoot} from 'react-dom/client'
import App from './App.tsx'
// import './index.css'
diff --git a/src/redux/authSlice.ts b/src/redux/authSlice.ts
index 9fc22f9..16dc583 100644
--- a/src/redux/authSlice.ts
+++ b/src/redux/authSlice.ts
@@ -5,6 +5,10 @@ import firebase from "firebase/compat/app";
// import {LOGIN_REQUEST , LOGIN_SUCCESS} from "./actionType.ts";
+type profile = {
+ name : string,
+ picture : string
+}
interface AuthState {
user : {name : string , profileURL : string} | null
@@ -14,7 +18,7 @@ interface AuthState {
}
export const initialState : AuthState = {
- user : sessionStorage.getItem('yt-user')? JSON.parse(sessionStorage.getItem('yt-user')) : null,
+ user : sessionStorage.getItem('yt-user')? JSON.parse(sessionStorage.getItem('yt-user') as string) : null,
loading: false,
accessToken : sessionStorage.getItem('yt-accessToken')? sessionStorage.getItem('yt-accessToken') : null,
error : null
@@ -34,14 +38,19 @@ export const login = createAsyncThunk<
const res = await auth.signInWithPopup(provider) ;
console.log(res)
- const accessToken = res.credential?.accessToken ;
+ const accessToken = (res.credential as firebase.auth.OAuthCredential)?.accessToken;
+ if (!accessToken) {
+ throw new Error("Access token is missing");
+ }
+
+ // const accessToken = (res.credential as credential)?.accessToken ;
const profile = {
- name: res.additionalUserInfo?.profile?.name as string,
- photoURL: res.additionalUserInfo?.profile?.picture as string,
+ name: (res.additionalUserInfo?.profile as profile)?.name as string,
+ profileURL: (res.additionalUserInfo?.profile as profile)?.picture as string,
};
- return { accessToken : accessToken!, profile }; // Return combined data
- } catch (error) {
+ return { accessToken : accessToken!, profile : profile }; // Return combined data
+ } catch (error : any) {
console.error('Login error:', error.message);
return rejectWithValue(error.message); // Reject with error message
}
@@ -50,7 +59,7 @@ export const login = createAsyncThunk<
export const logout = createAsyncThunk(
'auth/logout',
- async (_,{rejectWithValue}) => {
+ async (_) => {
await auth.signOut()
sessionStorage.removeItem('yt-accessToken')
sessionStorage.removeItem('yt-user')
@@ -124,7 +133,7 @@ export const createSliceStore = createSlice ( {
sessionStorage.setItem('yt-accessToken', state.accessToken)
sessionStorage.setItem('yt-user', JSON.stringify(state.user))
})
- .addCase(login.rejected, (state : AuthState, action : PayloadAction) => {
+ .addCase(login.rejected, (state : AuthState, action : PayloadAction) => {
state.loading = false;
state.accessToken = null
state.error = action.payload || 'Login failed'; // Set error message from rejected action
diff --git a/src/redux/channelSclice.ts b/src/redux/channelSclice.ts
index 8e0681e..96045d1 100644
--- a/src/redux/channelSclice.ts
+++ b/src/redux/channelSclice.ts
@@ -33,11 +33,11 @@ export const channelBYIDThunk = createAsyncThunk<
{id : string},
{rejectValue : string}
>(
- 'channel/getChannel',async ({id},{rejectWithValue, getState}) => {
+ 'channel/getChannel',async ({id},{rejectWithValue}) => {
try {
const res = await channelBYID(id)
return {channel : res.items[0]}
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
@@ -53,7 +53,7 @@ export const SubStatThunk = createAsyncThunk<
const res = await SubStat(channelID, getState)
console.log(res.items)
return {subscriptionStatus : res.items.length !== 0}
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.response.data)
}
}
@@ -64,16 +64,16 @@ export const getVideosByChannelThunk = createAsyncThunk<
{id : string},
{rejectValue : string}
>(
- 'channel/getVideosByChannel',async ({id},{rejectWithValue, getState}) => {
+ 'channel/getVideosByChannel',async ({id},{rejectWithValue}) => {
try {
const res = await getUploadPlayListID(id)
const uploadPlaylistId = res.items[0].contentDetails.relatedPlaylists.uploads
const channelres = await getVideosByChannel(uploadPlaylistId)
- const ids = []
- const channelIDs = []
- channelres.items.map((video)=> {
+ const ids: any[] = []
+ const channelIDs : any[] = []
+ channelres.items.map((video : any)=> {
ids.push( video.snippet?.resourceId?.videoId || video?.id?.videoId || video?.id || video?.contentDetails?.videoId )
channelIDs.push(video?.snippet?.channelId || video.snippet?.resourceId?.channelId)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
@@ -83,7 +83,7 @@ export const getVideosByChannelThunk = createAsyncThunk<
console.log(ids)
// console.log(icons)
return {channelVideos : channelres.items, duration : duration, channelIcon : icons}
- }catch (error){
+ }catch (error : any){
console.log(error.response.data)
return rejectWithValue(error.response.data)
}
diff --git a/src/redux/commentSlice.ts b/src/redux/commentSlice.ts
index 2f49404..8b2799f 100644
--- a/src/redux/commentSlice.ts
+++ b/src/redux/commentSlice.ts
@@ -20,12 +20,12 @@ export const GetCommentsThunk = createAsyncThunk<
{id : string},
{rejectValue : string}
>(
- 'comment/getComments',async ({id },{rejectWithValue, getState}) => {
+ 'comment/getComments',async ({id },{rejectWithValue }) => {
try {
const res = await GetComments(id)
- console.log(getState().auth.accessToken)
+ // console.log(getState().auth.accessToken)
return {comments : res.items}
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
@@ -38,12 +38,15 @@ export const postCommentsThunk = createAsyncThunk<
>(
'comment/postComments', async ({id, text}, {rejectWithValue, getState, dispatch})=>{
try {
+
+ if(!id) return
+
await postComments(text, getState, id)
setTimeout(()=>dispatch(GetCommentsThunk( { id : id })), 3000)
// console.log(getState().auth?.accessToken)
return
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.response.data)
}
}
diff --git a/src/redux/relatedVideoSlice.ts b/src/redux/relatedVideoSlice.ts
index 1a3da8d..899fd39 100644
--- a/src/redux/relatedVideoSlice.ts
+++ b/src/redux/relatedVideoSlice.ts
@@ -24,12 +24,12 @@ export const getReletedVideosTHunk = createAsyncThunk<
{rejectValue : string}
>(
'relatedVideos/getRelatedVideos',
- async ({ id } , {rejectWithValue, getState}) => {
+ async ({ id } , {rejectWithValue}) => {
try {
const res = await getReletedVideos(id)
- const ids = []
- const channelIDs = []
- res.items.map((video)=> {
+ const ids: any[] = []
+ const channelIDs: any[] = []
+ res.items.map((video : any)=> {
ids.push(video?.id?.videoId)
channelIDs.push(video?.snippet?.resourceId?.channelId || video?.snippet?.channelId || video?.channelId)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
@@ -41,7 +41,7 @@ export const getReletedVideosTHunk = createAsyncThunk<
const icons = await getIcon(channelIDs.join(","))
console.log(res)
return { relatedVideos : res.items, ViewsDuration : duration_and_Views, channelIcons : icons }
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.response.data)
}
}
diff --git a/src/redux/searchVideoSlice.ts b/src/redux/searchVideoSlice.ts
index aa98a7f..e7f087d 100644
--- a/src/redux/searchVideoSlice.ts
+++ b/src/redux/searchVideoSlice.ts
@@ -1,4 +1,4 @@
-import {createAsyncThunk , createSlice , PayloadAction} from "@reduxjs/toolkit";
+import {createAsyncThunk , createSlice } from "@reduxjs/toolkit";
import {getDurationView , getIcon , searchVideosByKeyword} from "../Data/fetchApi.ts";
interface searchState {
@@ -29,9 +29,9 @@ export const searchVideosByKeywordThunk = createAsyncThunk<
async ({ keyword } , {rejectWithValue}) => {
try {
const res = await searchVideosByKeyword(keyword)
- const ids = []
- const channelIDs = []
- res.items.map((video)=> {
+ const ids: any[] = []
+ const channelIDs : any[] = []
+ res.items.map((video : any)=> {
ids.push(video?.id?.videoId)
channelIDs.push(video?.snippet?.resourceId?.channelId || video?.snippet?.channelId)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
@@ -41,7 +41,7 @@ export const searchVideosByKeywordThunk = createAsyncThunk<
console.log('keyword',keyword)
// console.log('keyword',res.data.items)
return { videos : res.items, ViewsDuration : duration_and_Views, channelIcons : icons }
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
diff --git a/src/redux/selectVideoSlice.ts b/src/redux/selectVideoSlice.ts
index 3afc76e..a60d014 100644
--- a/src/redux/selectVideoSlice.ts
+++ b/src/redux/selectVideoSlice.ts
@@ -3,7 +3,7 @@ import { getVideosById} from "../Data/fetchApi.ts";
interface ItemState {
- videos : any[],
+ videos : { statistics : any }[],
// nextPageToken : string | null,
// activeCategory: string | null; // Ensure it's initialized properly
loading: boolean;
@@ -29,7 +29,7 @@ export const getVideosByIdThunk = createAsyncThunk<
try {
const res = await getVideosById(id)
return {videos : res.items[0] }
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
diff --git a/src/redux/subscriptionsSlice.ts b/src/redux/subscriptionsSlice.ts
index 0844400..4d67313 100644
--- a/src/redux/subscriptionsSlice.ts
+++ b/src/redux/subscriptionsSlice.ts
@@ -30,9 +30,9 @@ export const getsubscriptionsThunk = createAsyncThunk<
'subscription/getsubscriptions',async (_,{rejectWithValue, getState}) => {
try {
const res = await getsubscriptions(getState)
- const ids = []
- const channelIDs = []
- res.items.map((video)=> {
+ const ids : any[] = []
+ const channelIDs : any[] = []
+ res.items.map((video : any)=> {
ids.push(video?.id?.videoId || video?.id)
channelIDs.push(video?.snippet?.resourceId?.channelId || video?.snippet.channelId || video.channelId)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
@@ -41,7 +41,7 @@ export const getsubscriptionsThunk = createAsyncThunk<
const icons = await getIcon(channelIDs.join(","))
console.log(res.items)
return {subscriptions : res.items, ViewsDuration : duration_and_Views, channelIcons : icons}
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.response.data)
}
}
diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts
index ef6f61e..de1383b 100644
--- a/src/redux/videoSlice.ts
+++ b/src/redux/videoSlice.ts
@@ -1,6 +1,15 @@
import {createAsyncThunk , createSlice , PayloadAction} from "@reduxjs/toolkit";
import {getDurationView , getIcon , getVideosByKeyword , getyoutubeVideos} from "../Data/fetchApi.ts";
+interface YouTubeVideo {
+ id: { videoId?: string; contentDetails?: { videoId: string } } | string;
+ snippet: { channelId: string };
+}
+
+interface YouTubeResponse {
+ items: YouTubeVideo[];
+ nextPageToken: string;
+}
interface ItemState {
videos : any[],
@@ -33,22 +42,22 @@ export const getyoutubeVideosThunk = createAsyncThunk<
'yt_video/getvideos',
async (_, {rejectWithValue, getState}) => {
try {
- const res = await getyoutubeVideos(getState)
- const ids = []
- const channelIDs = []
- const title = []
- res.items.map((video)=> {
+ const res : YouTubeResponse = await getyoutubeVideos(getState)
+ const ids: string[] = []
+ const channelIDs: string[] = []
+ // const title: any[] = []
+ res.items.map((video : any)=> {
ids.push(video?.id?.videoId || video?.id || video?.contentDetails?.videoId)
channelIDs.push(video?.snippet?.channelId)
- title.push(video?.snippet.channelTitle)
+ // title.push(video?.snippet.channelTitle)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
})
const duration = await getDurationView(ids)
const icons = await getIcon(channelIDs.join(","))
// console.log(res.data.items)
- console.log(title)
- return { videos : res.items, nextPageToken : res.nextPageToken , activeCategory : getState().homeVideos.activeCategory, videoIds : ids, duration : duration, channelIcon : icons}
- }catch (error){
+ // console.log(title)
+ return { videos : res.items, nextPageToken : res.nextPageToken , activeCategory : (getState() as any).homeVideos.activeCategory, videoIds : ids, duration : duration, channelIcon : icons}
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
@@ -64,9 +73,9 @@ export const getVideosByKeywordThunk = createAsyncThunk<
try {
const res = await getVideosByKeyword(keyword,getState)
console.log('keyword',keyword)
- const ids = []
- const channelIDs = []
- res.items.map((video)=> {
+ const ids : any[] = []
+ const channelIDs: any[] = []
+ res.items.map((video : any)=> {
ids.push(video?.id?.videoId || video?.id || video?.contentDetails?.videoId)
channelIDs.push(video?.snippet?.channelId)
// return {videoIds : video?.id?.videoId || video?.id || video?.contentDetails?.videoId}
@@ -75,7 +84,7 @@ export const getVideosByKeywordThunk = createAsyncThunk<
const icons = await getIcon(channelIDs.join(","))
// console.log('keyword',res.data.items)
return { videos : res.items, nextPageToken : res.nextPageToken, activeCategory : keyword, videoIds : ids, duration : duration, channelIcon : icons }
- }catch (error){
+ }catch (error : any){
return rejectWithValue(error.message)
}
}
@@ -85,7 +94,11 @@ export const getVideosByKeywordThunk = createAsyncThunk<
export const videoSliceStore = createSlice({
name : 'yt_video',
initialState,
- reducers: {},
+ reducers: {
+ display(initialState){
+ initialState
+ }
+ },
extraReducers:(builder) => {
builder
.addCase(getyoutubeVideosThunk.fulfilled,(state : ItemState, action)=>{