From 60e6b4d85107d2a7ef90ce62903f29cb5f927784 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Mon, 28 Feb 2022 00:08:20 +0100 Subject: [PATCH] progress, bookmarking, homepage, resuming where left of, actual media view, navigation improvements for searching Co-authored-by: James Hawkins Co-authored-by: William Oldham --- .vscode/settings.json | 2 +- README.md | 22 ++-- src/App.tsx | 24 ++-- src/components/Text/DotList.tsx | 19 +++ src/components/layout/BrandPill.tsx | 2 +- src/components/layout/Loading.tsx | 2 +- src/components/layout/Navigation.tsx | 17 ++- src/components/layout/Paper.tsx | 14 ++ src/components/layout/SectionHeading.tsx | 3 +- src/components/media/EpisodeButton.tsx | 18 +++ src/components/media/MediaCard.tsx | 27 +--- src/components/media/VideoPlayer.tsx | 28 +++- src/components/media/WatchedMediaCard.tsx | 4 +- src/hooks/useSearchQuery.ts | 2 +- src/providers/index.ts | 5 + src/providers/methods/contentCache.ts | 9 ++ src/providers/methods/search.ts | 7 +- src/providers/types.ts | 4 +- src/state/bookmark/context.tsx | 100 ++++++++++++++ src/state/bookmark/index.ts | 1 + src/state/bookmark/store.ts | 45 +++++++ src/state/watched/context.tsx | 17 +-- src/views/MediaView.tsx | 153 ++++++++++++++++++++++ src/views/MovieView.tsx | 34 ----- src/views/SearchView.tsx | 64 +++++++-- src/views/SeriesView.tsx | 7 - 26 files changed, 511 insertions(+), 119 deletions(-) create mode 100644 src/components/Text/DotList.tsx create mode 100644 src/components/layout/Paper.tsx create mode 100644 src/components/media/EpisodeButton.tsx create mode 100644 src/providers/methods/contentCache.ts create mode 100644 src/state/bookmark/context.tsx create mode 100644 src/state/bookmark/index.ts create mode 100644 src/state/bookmark/store.ts create mode 100644 src/views/MediaView.tsx delete mode 100644 src/views/MovieView.tsx delete mode 100644 src/views/SeriesView.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index df15c3b2..490d5da2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "files.eol": "\n", "editor.detectIndentation": false, - "editor.formatOnSave": false, + "editor.formatOnSave": true, "editor.tabSize": 2 } \ No newline at end of file diff --git a/README.md b/README.md index 99ea4dbe..1f6e2679 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,18 @@ Check out [this project's issues](https://github.com/JamesHawkinss/movie-web/iss - [x] Add results list end - [x] Store watched percentage - [x] Add Brand tag top left -- [X] Add github and discord top right +- [x] Add github and discord top right - [x] Link Github and Discord in error boundary - [ ] Implement movie + series view - - [ ] Global state for media objects - - [ ] Styling for pages + - [x] Global state for media objects + - [x] Styling for pages + - [ ] loading video player view + error - [ ] Series episodes+seasons -- [ ] On back button, persist the search query and results -- [ ] Bookmarking -- [ ] Resume from where you left of -- [ ] Less spaghett video player view -- [ ] Homepage continue watching + bookmarks +- [x] On back button, persist the search query and results +- [x] Bookmarking +- [x] Resume from where you left of +- [ ] Less spaghett video player view (implement source that are not mp4) +- [x] Homepage continue watching + bookmarks - [x] Add provider stream method - [x] Better looking error boundary - [x] sort search results so they aren't sorted by provider @@ -57,10 +58,13 @@ Check out [this project's issues](https://github.com/JamesHawkinss/movie-web/iss - [ ] Migrate old video progress - [ ] Get rid of react warnings - [ ] Implement more scrapers -- [ ] Add 404 page for media (media not found, provider disabled, provider not found) & general (page not found) +- [ ] Add 404 page for media (media not found, provider disabled, provider not found) & general (page not found) <--- +- [x] Change text of "thats all we have" ## Todo's after rewrite - [ ] Less spaghetti versioned storage (typesafe and works functionally) +- [ ] Add a way to remove from continue watching +- [ ] i18n - [ ] better mobile search type selector - [ ] Custom video player diff --git a/src/App.tsx b/src/App.tsx index 0ef231ba..baa949cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,22 +1,24 @@ import { MWMediaType } from "providers"; import { Redirect, Route, Switch } from "react-router-dom"; -import { WatchedContextProvider } from "state/watched/context"; +import { BookmarkContextProvider } from "state/bookmark"; +import { WatchedContextProvider } from "state/watched"; import "./index.css"; -import { MovieView } from "./views/MovieView"; +import { MediaView } from "./views/MediaView"; import { SearchView } from "./views/SearchView"; -import { SeriesView } from "./views/SeriesView"; function App() { return ( - - - - - - - - + + + + + + + + + + ); } diff --git a/src/components/Text/DotList.tsx b/src/components/Text/DotList.tsx new file mode 100644 index 00000000..dc7b4dcd --- /dev/null +++ b/src/components/Text/DotList.tsx @@ -0,0 +1,19 @@ +export interface DotListProps { + content: string[]; + className?: string; +} + +export function DotList(props: DotListProps) { + return ( +

+ {props.content.map((item, index) => ( + + {index !== 0 ? ( + + ) : null} + {item} + + ))} +

+ ); +} diff --git a/src/components/layout/BrandPill.tsx b/src/components/layout/BrandPill.tsx index e71c3f92..d51e5104 100644 --- a/src/components/layout/BrandPill.tsx +++ b/src/components/layout/BrandPill.tsx @@ -5,7 +5,7 @@ export function BrandPill() { return (
- Movie Web + movie-web
) } diff --git a/src/components/layout/Loading.tsx b/src/components/layout/Loading.tsx index e12da6e2..14fab31e 100644 --- a/src/components/layout/Loading.tsx +++ b/src/components/layout/Loading.tsx @@ -6,7 +6,7 @@ export interface LoadingProps { export function Loading(props: LoadingProps) { return (
-
+
diff --git a/src/components/layout/Navigation.tsx b/src/components/layout/Navigation.tsx index af30be98..375878e6 100644 --- a/src/components/layout/Navigation.tsx +++ b/src/components/layout/Navigation.tsx @@ -1,13 +1,24 @@ import { IconPatch } from "components/buttons/IconPatch"; import { Icons } from "components/Icon"; import { DISCORD_LINK, GITHUB_LINK } from "mw_constants"; +import { ReactNode } from "react"; +import { Link } from "react-router-dom" import { BrandPill } from "./BrandPill"; -export function Navigation() { +export interface NavigationProps { + children?: ReactNode; +} + +export function Navigation(props: NavigationProps) { return (
-
- +
+
+ + + +
+ {props.children}
diff --git a/src/components/layout/Paper.tsx b/src/components/layout/Paper.tsx new file mode 100644 index 00000000..8659e97f --- /dev/null +++ b/src/components/layout/Paper.tsx @@ -0,0 +1,14 @@ +import { ReactNode } from "react"; + +export interface PaperProps { + children?: ReactNode, + className?: string, +} + +export function Paper(props: PaperProps) { + return ( +
+ {props.children} +
+ ) +} diff --git a/src/components/layout/SectionHeading.tsx b/src/components/layout/SectionHeading.tsx index d9f3c6aa..e341496b 100644 --- a/src/components/layout/SectionHeading.tsx +++ b/src/components/layout/SectionHeading.tsx @@ -8,11 +8,12 @@ interface SectionHeadingProps { children?: ReactNode; linkText?: string; onClick?: () => void; + className?: string; } export function SectionHeading(props: SectionHeadingProps) { return ( -
+

{props.icon ? ( diff --git a/src/components/media/EpisodeButton.tsx b/src/components/media/EpisodeButton.tsx new file mode 100644 index 00000000..1c5eccea --- /dev/null +++ b/src/components/media/EpisodeButton.tsx @@ -0,0 +1,18 @@ +export interface EpisodeProps { + progress?: number; + episodeNumber: number; +} + +export function Episode(props: EpisodeProps) { + return ( +

+
+ {props.episodeNumber} +
+ ); +} diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx index 95d1a49d..41eb2ff5 100644 --- a/src/components/media/MediaCard.tsx +++ b/src/components/media/MediaCard.tsx @@ -1,38 +1,20 @@ import { convertMediaToPortable, getProviderFromId, - MWMedia, + MWMediaMeta, MWMediaType, } from "providers"; import { Link } from "react-router-dom"; import { Icon, Icons } from "components/Icon"; import { serializePortableMedia } from "hooks/usePortableMedia"; +import { DotList } from "components/text/DotList"; export interface MediaCardProps { - media: MWMedia; + media: MWMediaMeta; watchedPercentage: Number; linkable?: boolean; } -export interface MediaMetaProps { - content: string[]; -} - -function MediaMeta(props: MediaMetaProps) { - return ( -

- {props.content.map((item, index) => ( - - {index !== 0 ? ( - - ) : null} - {item} - - ))} -

- ); -} - function MediaCardContent({ media, linkable, @@ -68,7 +50,8 @@ function MediaCardContent({ {/* card content */}

{media.title}

-
diff --git a/src/components/media/VideoPlayer.tsx b/src/components/media/VideoPlayer.tsx index 17fa94ec..8784f3ed 100644 --- a/src/components/media/VideoPlayer.tsx +++ b/src/components/media/VideoPlayer.tsx @@ -1,22 +1,48 @@ +import { IconPatch } from "components/buttons/IconPatch"; +import { Icons } from "components/Icon"; +import { Loading } from "components/layout/Loading"; import { MWMediaStream } from "providers"; import { useRef } from "react"; export interface VideoPlayerProps { source: MWMediaStream; + startAt?: number; onProgress?: (event: ProgressEvent) => void; } +export function SkeletonVideoPlayer(props: { error?: boolean }) { + return ( +
+ {props.error ? ( +
+ +

Couldn't get your stream

+
+ ) : ( +
+ +

Getting your stream...

+
+ )} +
+ ); +} + export function VideoPlayer(props: VideoPlayerProps) { const videoRef = useRef(null); const mustUseHls = props.source.type === "m3u8"; return (
{/* results view */} @@ -162,8 +162,46 @@ export function SearchView() { searchQuery={debouncedSearch} clear={() => setSearch({ searchQuery: "" })} /> - ) : null} + ) : ( + + )} ); } + +function ExtraItems() { + const { bookmarkStore } = useBookmarkContext(); + const { watched } = useWatchedContext(); + const watchedItems = watched.items.filter( + (v) => !getIfBookmarkedFromPortable(bookmarkStore, v) + ); + + if (watchedItems.length === 0 && bookmarkStore.bookmarks.length === 0) + return null; + + return ( +
+ {bookmarkStore.bookmarks.length > 0 ? ( + + {bookmarkStore.bookmarks.map((v) => ( + + ))} + + ) : null} + {watchedItems.length > 0 ? ( + + {watchedItems.map((v) => ( + + ))} + + ) : null} +
+ ); +} diff --git a/src/views/SeriesView.tsx b/src/views/SeriesView.tsx deleted file mode 100644 index f535ca0f..00000000 --- a/src/views/SeriesView.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export function SeriesView() { - return ( -
-

Series view here

-
- ) -}