From 6885275f421ab8d00de84e5af4be44da2ce4becc Mon Sep 17 00:00:00 2001 From: Jerry Yasir Date: Fri, 20 Nov 2020 22:07:50 -0500 Subject: [PATCH] Add files via upload --- .../reactSpFx/ReactSpFxWebPart.manifest.json | 3 +- .../webparts/reactSpFx/ReactSpFxWebPart.ts | 13 +- .../reactSpFx/components/IReactSpFxProps.ts | 18 ++- .../components/ReactSpFx.module.scss | 1 + .../reactSpFx/components/ReactSpFx.tsx | 25 +--- .../SportVideoListFilmStripView.tsx | 112 +++++++++++++++ .../components/SportsHighlightsList.tsx | 133 ++++++++++-------- .../reactSpFx/components/SportsVideo.tsx | 4 +- .../reactSpFx/components/SportsVideoList.tsx | 6 +- .../FilmstripLayout.module.scss | 117 +++++++++++++++ .../FilmstripLayout.module.scss.d.ts | 16 +++ .../filmstripLayout/FilmstripLayout.tsx | 117 +++++++++++++++ .../components/filmstripLayout/index.ts | 1 + 13 files changed, 468 insertions(+), 98 deletions(-) create mode 100644 samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportVideoListFilmStripView.tsx create mode 100644 samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/FilmstripLayout.module.scss create mode 100644 samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/FilmstripLayout.module.scss.d.ts create mode 100644 samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/FilmstripLayout.tsx create mode 100644 samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/index.ts diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.manifest.json b/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.manifest.json index 196030a2e..357929c7c 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.manifest.json +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.manifest.json @@ -21,7 +21,8 @@ "description": { "default": "Soccer Hightlights Web Parts show latest hightlights from around the world." }, "officeFabricIconFontName": "Soccer", "properties": { - "tile": "Soocer Highlights" + "title": "Soccer Highlights", + "pageSize": 5 } }] } diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.ts b/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.ts index 0530259e4..c0d53260b 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.ts +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/ReactSpFxWebPart.ts @@ -5,6 +5,7 @@ import { IPropertyPaneConfiguration, PropertyPaneTextField, PropertyPaneSlider, + PropertyPaneToggle, } from '@microsoft/sp-property-pane'; import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; @@ -18,6 +19,7 @@ export interface IReactSpFxWebPartProps { title: string; pageSize: number; displayMode: DisplayMode; + showFlatMode: boolean; updateProperty: (value: string) => void; } @@ -29,7 +31,8 @@ export default class ReactSpFxWebPart extends BaseClientSideWebPart {this.properties.title = value;}, onConfigure: () => { this.context.propertyPane.open(); @@ -66,10 +69,14 @@ export default class ReactSpFxWebPart extends BaseClientSideWebPart void; onConfigure: () => void; } -export interface IVidesList { +export interface IVideosList { videos: IVideo[]; } @@ -19,18 +20,16 @@ export interface IVideo { } export interface ISportsHighlightsState { - sportHighlightState: []; + sportHighlightState: any; } export interface ISportsHighlightPagingState { - currentPage: number; - indexOfLastHighlight: number; - indexOfFirstHighlight: number; - highLightsPerPage: number; + pagedSportHighlights?: ISportsHighlightProps[]; + slicedSportHighlights?: ISportsHighlightProps[]; } export interface ISportsHightLightsProps { pageSize:number; - sportsHighlights: []; + showFlatMode: boolean; } export interface ISide { @@ -41,8 +40,13 @@ export interface ICompetition{ id: number; } +export interface ISportsHighlights { + highLights?: ISportsHighlightProps[]; +} + export interface ISportsHighlightProps { title: string; + embed: string id: string; date: Date; side1: ISide; diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.module.scss b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.module.scss index fa33b1bd1..5e6e9ed96 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.module.scss +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.module.scss @@ -11,6 +11,7 @@ border: 1px solid lightblue; height: 100px; padding: 10px 0; + width: 100%; display: flex; justify-content: center; } diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.tsx b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.tsx index 941a2f552..7177b77f2 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.tsx +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/ReactSpFx.tsx @@ -6,35 +6,18 @@ import SportsHighlightsList from "./SportsHighlightsList"; import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle"; import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder"; -import axios from "axios"; + import { setVirtualParent } from "office-ui-fabric-react"; import SportsHighlights from "./SportsHighlightsList"; import "bootstrap/dist/css/bootstrap.css"; -export default class ReactSpFx extends React.Component< - IReactSpFxProps, - ISportsHighlightsState -> { +export default class ReactSpFx extends React.Component { public constructor(props: IReactSpFxProps, state: ISportsHighlightsState) { super(props); - this.state = { - sportHighlightState: [], - }; - } - - GetData = async () => { - const resp = await axios.get(`https://www.scorebat.com/video-api/v1/`); - const data = await resp.data; - this.setState({ sportHighlightState: data }); - }; - - async componentDidMount() { - this.GetData(); } public render(): React.ReactElement { const globalComponent = this; - console.log(this.props.pageSize); return (
{!this.props.title && ( @@ -56,9 +39,7 @@ export default class ReactSpFx extends React.Component<
)} - ); diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportVideoListFilmStripView.tsx b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportVideoListFilmStripView.tsx new file mode 100644 index 000000000..4c9728384 --- /dev/null +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportVideoListFilmStripView.tsx @@ -0,0 +1,112 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import { ISportsHighlightProps, ISportsHighlights } from "./IReactSpFxProps"; +import SportsVideo from "./SportsVideo"; +import ReactMarkdownWithHtml from "react-markdown/with-html"; +import { FilmstripLayout } from './filmstripLayout/index'; +import styles from './filmstripLayout/FilmstripLayout.module.scss'; + +import { + DocumentCard, + DocumentCardActivity, + DocumentCardPreview, + DocumentCardDetails, + DocumentCardTitle, + IDocumentCardPreviewProps, + DocumentCardLocation, + DocumentCardType, +} from "office-ui-fabric-react/lib/DocumentCard"; + +import { ImageFit } from "office-ui-fabric-react/lib/Image"; +export interface IDialogState +{ + isDialogOpen: boolean; +} +export default class SportVideoListFilmStripView extends React.Component< + ISportsHighlights, + IDialogState +> { + constructor(props: ISportsHighlights, state: IDialogState) { + super(props); + this.state = { + isDialogOpen: false, + }; + } + openDialog = (video: ISportsHighlightProps) => { + console.log("I awas clicked:" + video.title); + this.setState({ isDialogOpen: true }); + }; + handleClose = () => this.setState({ isDialogOpen: false }); + + public render(): React.ReactElement { + const videos = this.props.highLights; + + return ( +
+
+ + {this.props.highLights.map((video: ISportsHighlightProps, i) => { + let videoDate = new Date(video.date.toString()); + const previewProps: IDocumentCardPreviewProps = { + previewImages: [ + { + previewImageSrc: video.thumbnail, + imageFit: ImageFit.cover, + height: 130, + }, + ], + }; + + return ( +
+ ) => + this.openDialog(video) + } + > + {/* */} + + {/* */} +
+ + + +
+ ); + })} + +
+
+ ); + } +} diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsHighlightsList.tsx b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsHighlightsList.tsx index a8f679866..d3c3386f1 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsHighlightsList.tsx +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsHighlightsList.tsx @@ -3,90 +3,103 @@ import ReactDOM from "react-dom"; import { ISportsHightLightsProps, ISportsHighlightPagingState, - IVideo, + ISportsHighlightsState, + ISportsHighlightProps, } from "./IReactSpFxProps"; -import SportsHighlight from "./SportsHighlight"; +//import SportsHighlight from "./SportsHighlight"; +import SportVideoListFilmStripView from "./SportVideoListFilmStripView"; import Paging from "react-paging"; -import Pagination from "./Pagination"; +import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; +import axios from "axios"; +import SportsVideoList from "./SportsVideoList"; + export default class SportsHighlightsList extends React.Component< ISportsHightLightsProps, ISportsHighlightPagingState > { - constructor(props) { + constructor( + props: ISportsHightLightsProps, + state: ISportsHighlightPagingState + ) { super(props); this.state = { - currentPage: 1, - indexOfFirstHighlight: 1, - indexOfLastHighlight: 5, - highLightsPerPage: this.props.pageSize, + pagedSportHighlights: [], + slicedSportHighlights: [], }; } - - paginate = (page) => { - console.clear(); - - const indexOfLastHighlight = - this.state.currentPage * this.state.highLightsPerPage; - const indexOfFirstHighlight = - indexOfLastHighlight - this.state.highLightsPerPage; - - this.setState({ - currentPage: page, - indexOfLastHighlight: indexOfLastHighlight, - indexOfFirstHighlight: indexOfFirstHighlight, - }); + public GetData = async () => { + const resp = await axios.get(`https://www.scorebat.com/video-api/v1/`); + const data : ISportsHighlightProps[] = await resp.data; + let slicedItems : ISportsHighlightProps[] = data.slice(0, this.props.pageSize); + this.setState({ pagedSportHighlights: data, slicedSportHighlights: slicedItems }); }; - //paginate = (pageNumber) => setCurrentPage(pageNumber); - - render(): React.ReactElement { - const sportsHighlights = this.props.sportsHighlights; - var { - currentPage, - indexOfFirstHighlight, - indexOfLastHighlight, - } = this.state; + async componentDidMount() { + console.log("Mounted"); + this.GetData(); + } - if (typeof indexOfFirstHighlight === "undefined" || indexOfFirstHighlight == 0) - { - indexOfFirstHighlight=1 - } - if ( - typeof indexOfFirstHighlight === "undefined" || - indexOfFirstHighlight == 0 - ) { - indexOfFirstHighlight = 1; - } - const CurrentsportsHighlights = this.props.sportsHighlights.slice( - indexOfFirstHighlight, - indexOfLastHighlight + + public render(): React.ReactElement { + + let pageCountDivisor: number = this.props.pageSize; + let pageCount: number; + let pageButtons = []; + let highlightItems = this.state.pagedSportHighlights; + + let _pagedButtonClick = (pageNumber: number, listData: any) => { + let startIndex: number = (pageNumber - 1) * pageCountDivisor; + let endIndex = startIndex + pageCountDivisor; + let listItemsCollection = [...listData]; + let slicedItems: ISportsHighlightProps[] = listItemsCollection.slice( + startIndex, + endIndex ); + this.setState({ + slicedSportHighlights: slicedItems + }); + }; - console.clear(); - console.log("indexOfFirstHighlight:" + indexOfFirstHighlight); - console.log("indexOfLastHighlight : " + indexOfLastHighlight); - console.log("currentPage :" + currentPage); - console.log("Page Size :" + this.props.pageSize); + // const pagedItems: JSX.Element = ( + // + // ); - //this.updateLastPage(currentPage); + var pagedItems: JSX.Element = null; + if(!this.props.showFlatMode){ + pagedItems = (); + } + else{ + pagedItems = ( ); + } + + if (highlightItems.length > 0) { + pageCount = Math.ceil(highlightItems.length / pageCountDivisor); + } + for (let i = 0; i < pageCount; i++) { + pageButtons.push( + { + _pagedButtonClick(i + 1, highlightItems); + }} + > + {" "} + {i + 1}{" "} + + ); + } return (
-
- +
+
{pageButtons}
-
- {CurrentsportsHighlights.map((highLight, i) => ( - - ))} +
+
+
{pagedItems}
); diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideo.tsx b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideo.tsx index adec9d9ea..127779ce3 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideo.tsx +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideo.tsx @@ -10,14 +10,14 @@ export default class SportsVideo extends React.Component { return (
{title}
diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideoList.tsx b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideoList.tsx index 360ab8bef..4f65cd838 100644 --- a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideoList.tsx +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/SportsVideoList.tsx @@ -1,14 +1,14 @@ import React from "react"; import ReactDOM from "react-dom"; -import { IVidesList } from "./IReactSpFxProps"; +import { IVideosList } from "./IReactSpFxProps"; import SportsVideo from "./SportsVideo"; import ReactMarkdownWithHtml from "react-markdown/with-html"; -export default class SportsVideoList extends React.Component { +export default class SportsVideoList extends React.Component { public render() { const videos = this.props.videos; return ( -
+
{this.props.videos.map((video, i) => ( { + let ref: React.MutableRefObject = useRef( + null + ); + let size: ComponentSize = useComponentSize(ref); + let { width } = size; + + // // the slick slider used in normal views + let _slider: React.MutableRefObject = useRef(null); + + SPComponentLoader.loadCss( + "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" + ); + SPComponentLoader.loadCss( + "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" + ); + + // slick seems to have an issue with having "infinite" mode set to true and having less items than the number of slides per page + // set infinite to true only if there are more than 3 children + let numSlides: number = 3; + if (width) { + if (width > 927) { + numSlides = 4; + } else if (width <= 695) { + numSlides = 2; + } + } + + var isInfinite: boolean = React.Children.count(props.children) > numSlides; + var settings: any = { + accessibility: true, + arrows: false, + autoplaySpeed: 5000, + dots: true, + customPaging: (i: number) => { + return ( + +
+ +
+
+ ); + }, + infinite: isInfinite, + slidesToShow: numSlides, + slidesToScroll: numSlides, + speed: 500, + centerPadding: styles.centerPadding, + pauseOnHover: true, + variableWidth: false, + useCSS: true, + rows: 1, + respondTo: "slider", + }; + + return ( +
+
+ + {props.children} + +
_slider.current.slickPrev()} + > + +
+
_slider.current.slickNext()} + > + +
+
+
+ ); +}; diff --git a/samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/index.ts b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/index.ts new file mode 100644 index 000000000..db53a6c19 --- /dev/null +++ b/samples/react-soccer-highlights/src/webparts/reactSpFx/components/filmstripLayout/index.ts @@ -0,0 +1 @@ +export * from "./FilmstripLayout";