diff --git a/package.json b/package.json index 9b3ea68..73dd92b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sc2-campaign-manager", - "version": "0.5.2-alpha", + "version": "0.5.3-alpha", "description": "A Campaign Manager for StarCraft II. ", "main": "main.js", "build": { diff --git a/src/classes/Campaign.ts b/src/classes/Campaign.ts index 1689fae..07a75aa 100644 --- a/src/classes/Campaign.ts +++ b/src/classes/Campaign.ts @@ -48,6 +48,7 @@ export interface ICampaign { "patchNotes":Array, "screenshots":Array, "videos"?:Array, + "state"?:string, [key: string]: string|number|object|boolean|ISC2Map|ISC2Mod }; @@ -148,6 +149,7 @@ export default class Campaign { static downloadCampaign = (campaign:ICampaign) => { const installDir = Campaign.getCampaignsInstallDir(); + Downloader.pushCampaign(campaign); //ipcRenderer.send(msg.DOWNLOAD_CAMPAIGN, {...campaign, installDir:Campaign.getCampaignsInstallDir()}); diff --git a/src/classes/Downloader.ts b/src/classes/Downloader.ts index f776139..f57da15 100644 --- a/src/classes/Downloader.ts +++ b/src/classes/Downloader.ts @@ -28,12 +28,27 @@ interface IDownloadSet { [key: string]: IDownload; } +const getCampaignFromStore = (campaignId:string) => { + const campaigns = store.getState().campaignState.campaigns; + const campaignIndex = campaigns.findIndex(c => c.id === campaignId); + return campaigns[campaignIndex] + +} + +const setCampaignInStore = (campaignId:string,campaign:ICampaign) => { + const campaigns = store.getState().campaignState.campaigns; + const campaignIndex = campaigns.findIndex(c => c.id === campaignId); + store.dispatch(setCampaign(campaign,campaignIndex)); +} + export default class Downloader { static downloads: IDownloadSet; static progress: number = 0; + static pushCampaign(campaign: ICampaign) { + console.log("pushCampaign"); - let sourcesbyKey: { [key: string]: ISource } = {}; + const mods: Array = [...campaign.mods, ...campaign.maps]; const sources = _.uniqWith( mods.map( @@ -60,11 +75,24 @@ export default class Downloader { ); Promise.all(promises).then(data => { console.log("downloads have finished for", campaign.id); + const newCampaign:ICampaign = { + ...getCampaignFromStore(campaign.id), + installed:Campaign.isCampaignInstalled(getCampaignFromStore(campaign.id)), + progress:0, + state:"ready" + }; + setCampaignInStore(newCampaign.id,newCampaign) }); + + const newCampaign:ICampaign = { + ...getCampaignFromStore(campaign.id), + state:"downloading" + }; + setCampaignInStore(newCampaign.id,newCampaign) + } static async downloadSource(source: ISource, index: number) { let timer = Date.now(); - const tempPath = path.join( app.getPath("temp"), app.getName(), @@ -87,6 +115,12 @@ export default class Downloader { } else { this.copyMaps(source.files[0], tempFullName); } + const newCampaign:ICampaign = { + ...getCampaignFromStore(source.campaignId), + installed:Campaign.isCampaignInstalled(getCampaignFromStore(source.campaignId)), + state:"ready" + }; + setCampaignInStore(newCampaign.id,newCampaign) }); dl.pipe(ws); }) @@ -192,12 +226,10 @@ export default class Downloader { [campaignId]: download }; console.log(campaignId, download.progress); - const campaigns = store.getState().campaignState.campaigns; - const campaignIndex = campaigns.findIndex(c => c.id === campaignId); - const campaign = { - ...campaigns[campaignIndex], + const newCampaign:ICampaign = { + ...getCampaignFromStore(campaignId), progress:download.progress }; - store.dispatch(setCampaign(campaign,campaignIndex)); + setCampaignInStore(campaignId,newCampaign) } } diff --git a/src/components/CampaignDetails.tsx b/src/components/CampaignDetails.tsx index 02cba08..7e65014 100644 --- a/src/components/CampaignDetails.tsx +++ b/src/components/CampaignDetails.tsx @@ -1,8 +1,8 @@ import React, { FC } from 'react'; -import { HashRouter as Router, Route, NavLink, Redirect, Switch} from "react-router-dom"; -import ReactMarkdown from 'react-markdown' +import { HashRouter as Router, Route, NavLink, Redirect, Switch } from "react-router-dom"; +import ReactMarkdown from 'react-markdown' -import Campaign, {ICampaign, IAuthor, IPatchNote} from '../classes/Campaign' +import Campaign, { ICampaign, IAuthor, IPatchNote } from '../classes/Campaign' //import Lightbox as Lightbox2 from 'react-lightbox-component'; import DownloadBar from './DownloadBar' import Lightbox from 'react-images' @@ -10,108 +10,128 @@ import { MapStateToProps, MapDispatchToProps, connect } from 'react-redux'; import { AppState } from '../store'; -const emptyAuthor:IAuthor = { - "id":"", - "name":"", - "email":"", - "campaigns":[] +const emptyAuthor: IAuthor = { + "id": "", + "name": "", + "email": "", + "campaigns": [] }; -function PatchNotes(props:any){ - const patchNotes:Array = props.patchNotes; - console.log("PatchNotes",patchNotes) +function PatchNotes(props: any) { + const patchNotes: Array = props.patchNotes; + console.log("PatchNotes", patchNotes) return ( - - {patchNotes.map((patchNote,i:number) => -
-

{patchNote.version} ()

- -
- )} -
+ + {patchNotes.map((patchNote, i: number) => +
+

{patchNote.version} ()

+ +
+ )} +
); } interface ICampaignDetailsProps { - "campaign"?:ICampaign, - "path"?:string, - "selectedCampaignAuthor"?:IAuthor, - "onPlayCampaignClick":(campaign:ICampaign,mapIndex?:number)=>void, - "onUpdateCampaignClick"?:(campaign:ICampaign)=>void, - "onDownloadCampaignClick":(campaign:ICampaign)=>void + "campaign"?: ICampaign, + "path"?: string, + "selectedCampaignAuthor"?: IAuthor, + "onPlayCampaignClick": (campaign: ICampaign, mapIndex?: number) => void, + "onUpdateCampaignClick"?: (campaign: ICampaign) => void, + "onDownloadCampaignClick": (campaign: ICampaign) => void } -const CampaignDetails:FC = (props) => { - const { - selectedCampaignAuthor, - onPlayCampaignClick, - onUpdateCampaignClick, +const CampaignDetails: FC = (props) => { + const { + selectedCampaignAuthor, + onPlayCampaignClick, + onUpdateCampaignClick, onDownloadCampaignClick, path } = props - const campaign = (props.campaign)?props.campaign:Campaign.emptyCampaign(); + const campaign = (props.campaign) ? props.campaign : Campaign.emptyCampaign(); const { - id, - name, + id, + name, author, - description, - maps, - lastUpdated, - patchNotes, + description, + maps, + lastUpdated, + patchNotes, screenshots, - videos, - installed, - progress + videos, + installed, + progress, + state } = campaign; - const basePath = path?path:"/campaign" + const basePath = path ? path : "/campaign" //const author:IAuthor = (selectedCampaignAuthor)?selectedCampaignAuthor:emptyAuthor; - const isCampaignInstalled:boolean = installed;//!Campaign.isCampaignInstalled(campaign); + const isCampaignInstalled: boolean = installed;//!Campaign.isCampaignInstalled(campaign); const onDownloadClick = onDownloadCampaignClick; - const downloadProgress:number = (progress)?progress:0; + const downloadProgress: number = (progress) ? progress : 0; return ( - -
- ( - - )}/> -
-
- {(isCampaignInstalled) && (maps.length > 0) && - - - {/* */} - - } - {(!isCampaignInstalled) && (maps.length > 0) && - - } - {(maps.length === 0) && - <> - + {/* */} + + } + {(!isCampaignInstalled) && (maps.length > 0) && (state!=="downloading") && + + } + {(!isCampaignInstalled) && (maps.length > 0) && (state==="downloading") && + + } + {(maps.length === 0) && + <> + -

This campaign has no maps listed.

- - } - -
-

{name}

-

- By {author}. Last Updated: -

-

- Project URL:  +

This campaign has no maps listed.

+ + } + + +

{name}

+

+ By {author}. Last Updated: +

+

+ Project URL:  - https://www.sc2mapster.com/projects/{id} - -

- {/* + https://www.sc2mapster.com/projects/{id} + +

+ {/*

Tagged under {(isCampaignInstalled) && @@ -122,130 +142,130 @@ const CampaignDetails:FC = (props) => { }

*/} - {(!isCampaignInstalled) && - - } + {(!isCampaignInstalled) && + + } - -
-
-
- - Description + + +
+
+ + Description - - Screenshots + + Screenshots - - Patch Notes + + Patch Notes - - Maps + + Maps -
-
    -
  • Maps: {maps.length}
  • -
- -
- - -
- {(videos) && - - - } - "_blank"} - /> -
- } /> - -
- { - screenshots.map(({src,description})=>{ - return ( -
- -
{description?description:"Caption"}
-
- ); - }) - } -
- } /> - - - - } /> - -
- {maps.map(({name,description,destination},index) => - -
-
-

{name}

- {description && - <> -

Description:

- "_blank"} - /> - +
+
    +
  • Maps: {maps.length}
  • +
+ +
+ + +
+ {(videos) && + + + } + "_blank"} + /> +
+ } /> + +
+ { + screenshots.map(({ src, description }) => { + return ( +
+ +
{description ? description : "Caption"}
+
+ ); + }) } -
-
-
+ } /> + + + + } /> + +
+ {maps.map(({ name, description, destination }, index) => + +
+
+

{name}

+ {description && + <> +

Description:

+ "_blank"} + /> + + } +
+
+ -
-
-
- )} -
- } /> - - - - + + + + )} + + } /> + + + +
- + ); } - -const mapStateToProps:MapStateToProps = (state,ownProps) => { - const {campaignState} = state; - const {selectedIndex, campaigns} = campaignState; + +const mapStateToProps: MapStateToProps = (state, ownProps) => { + const { campaignState } = state; + const { selectedIndex, campaigns } = campaignState; const props = { - "campaign":campaigns[selectedIndex], + "campaign": campaigns[selectedIndex], "index": selectedIndex } - return {...ownProps, ...props}; + return { ...ownProps, ...props }; }; -const mapDispatchToProps:MapDispatchToProps = (dispatch,ownProps) => { +const mapDispatchToProps: MapDispatchToProps = (dispatch, ownProps) => { return { ...ownProps, /*setCampaign: (campaign, index) => { @@ -257,4 +277,4 @@ const mapDispatchToProps:MapDispatchToProps { props.setCampaignsRemote(campaigns.map( campaign => ({ - ...campaign, + ...campaign, + state:"ready", installed:Campaign.isCampaignInstalled(campaign) }) )); @@ -45,7 +46,8 @@ class Home extends Component { //campaigns.forEach(campaign => Downloader.pushCampaign(campaign)) props.setCampaignsLocal(campaigns.map( campaign => ({ - ...campaign, + ...campaign, + state:"ready", installed:Campaign.isCampaignInstalled(campaign) }) ));