Skip to content

Commit

Permalink
fix: misc improvements and corrections (#47)
Browse files Browse the repository at this point in the history
* fix: misc improvements and corrections

* Added logging to check if git repo

Co-authored-by: ZigTag <[email protected]>
  • Loading branch information
Benjozork and ZigTag authored Jan 10, 2021
1 parent 202b48c commit 4fc4f63
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 88 deletions.
4 changes: 0 additions & 4 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ app.on('activate', () => {
// code. You can also put them in separate files and import them here.

function setupDefaultInstallPath(app: App) {
if (!settings.has('mainSettings.apiRelease')) {
settings.set('mainSettings.apiRelease', 'production');
}

if (!settings.has('mainSettings.msfsPackagePath')) {
let userPath = null;

Expand Down
100 changes: 71 additions & 29 deletions src/renderer/components/AircraftSection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ import {
DownloadProgress,
UpdateButton,
InstalledButton,
CancelButton, DetailsContainer, VersionHistoryContainer, LeftContainer, TopContainer, MSFSIsOpenButton
CancelButton,
DetailsContainer,
VersionHistoryContainer,
LeftContainer,
TopContainer,
MSFSIsOpenButton,
UpdateReason,
UpdateContainer
} from './styles';
import Store from 'electron-store';
import * as fs from "fs";
Expand All @@ -40,10 +47,16 @@ type Props = {
let controller: AbortController;
let signal: AbortSignal;

const UpdateReasonMessages = {
NEW_RELEASE_AVAILABLE: "New release available",
VERSION_CHANGED: "New version selected",
};

const index: React.FC<Props> = (props: Props) => {
const [selectedVariant] = useState<ModVariant>(props.mod.variants[0]);
const [selectedTrack, setSelectedTrack] = useState<ModTrack>(handleFindInstalledTrack());
const [needsUpdate, setNeedsUpdate] = useState<boolean>(false);
const [needsUpdateReason, setNeedsUpdateReason] = useState<string>();

const [isInstalled, setIsInstalled] = useState<boolean>(false);
const [isInstalledAsGitRepo, setIsInstalledAsGitRepo] = useState<boolean>(false);
Expand All @@ -67,10 +80,16 @@ const index: React.FC<Props> = (props: Props) => {
const isDownloading = download?.progress >= 0;

useEffect(() => {
checkForUpdates(selectedTrack);
checkIfMSFS();
checkForUpdates();
const checkMsfsInterval = setInterval(checkIfMSFS, 5_000);

return () => clearInterval(checkMsfsInterval);
}, []);

useEffect(() => {
checkForUpdates();
}, [selectedTrack]);

function findBuildTime(installDir: string) {
const buildInfo = `${installDir}\\build_info.json`;
if (fs.existsSync(buildInfo)) {
Expand All @@ -82,51 +101,80 @@ const index: React.FC<Props> = (props: Props) => {
}
}

async function checkForUpdates(track: ModTrack) {
async function checkForUpdates() {
const localLastTrack = settings.get('cache.' + props.mod.key + '.lastInstalledTrack');
const localLastUpdate = settings.get('cache.' + props.mod.key + '.lastUpdated');
const localLastBuildDate = settings.get('cache.' + props.mod.key + '.lastBuildTime');

const res = await fetch(track.url, { method: 'HEAD' });
const res = await fetch(selectedTrack.url, { method: 'HEAD' });

const webLastUpdate = res.headers.get('Last-Modified').toString();

const installDir = `${settings.get('mainSettings.msfsPackagePath')}\\${props.mod.targetDirectory}\\`;

if (fs.existsSync(installDir)) {
setIsInstalled(true);
console.log('Installed');

// Check for git install
console.log('Checking for git install');
try {
const symlinkPath = fs.readlinkSync(installDir);
if (symlinkPath) {
if (fs.existsSync(symlinkPath + '\\..\\.git\\')) {
console.log('Is git repo');
setIsInstalledAsGitRepo(true);
return;
}
}
} catch {
console.log('Is not git repo');
setIsInstalledAsGitRepo(false);
}

if (typeof localLastUpdate === "string") {
if (typeof localLastBuildDate === "string") {
if ((localLastUpdate === webLastUpdate) && (localLastBuildDate === findBuildTime(installDir))) {
console.log("Is Updated");
setNeedsUpdate(false);
console.log(`Checking for track '${selectedTrack.name}' being installed...`);
if (typeof localLastTrack === "string") {
if (localLastTrack !== selectedTrack.name) {
// The installed track is not the same - require update

setNeedsUpdate(true);
setNeedsUpdateReason(UpdateReasonMessages.VERSION_CHANGED);
} else {
// We are still on the same track - check the installed build

if (typeof localLastUpdate === "string") {
// There was an update before - check if that build is the latest

if (typeof localLastBuildDate === "string") {
if ((localLastUpdate === webLastUpdate) && (localLastBuildDate === findBuildTime(installDir))) {
setNeedsUpdate(false);
console.log("Is Updated");
} else {
setNeedsUpdate(true);
setNeedsUpdateReason(UpdateReasonMessages.NEW_RELEASE_AVAILABLE);
console.log("Is not Updated");
}
} else {
setNeedsUpdate(true);
setNeedsUpdateReason(UpdateReasonMessages.NEW_RELEASE_AVAILABLE);
console.log("Needs update to register build file to cache");
}
} else {
setNeedsUpdate(true);
console.log("Is not Updated");
setIsInstalled(false);
console.log("Failed");
}
} else {
setNeedsUpdate(true);
console.log("Needs update to register build file to cache");
}
} else {
setIsInstalled(false);
console.log("Failed");
// Don't know if the same track is installed - assume the worst
setNeedsUpdate(true);
setNeedsUpdateReason(UpdateReasonMessages.VERSION_CHANGED);
console.log('Don\'t know which track');
}

} else {
setIsInstalled(false);
setNeedsUpdate(false);
console.log('Not installed');
}
}

Expand Down Expand Up @@ -234,7 +282,6 @@ const index: React.FC<Props> = (props: Props) => {

async function findAndSetTrack(key: string) {
const newTrack = selectedVariant.tracks.find(x => x.key === key);
await checkForUpdates(newTrack);
setSelectedTrack(newTrack);
}

Expand Down Expand Up @@ -280,16 +327,6 @@ const index: React.FC<Props> = (props: Props) => {
}
}

// function handleLastInstalledTrackName() {
// const name = settings.get('cache.' + props.mod.key + '.lastInstalledTrack');
//
// if (typeof name === "string") {
// return name;
// } else {
// return "Development";
// }
// }

return (
<Container wait={wait}>
<HeaderImage>
Expand All @@ -302,7 +339,12 @@ const index: React.FC<Props> = (props: Props) => {
{!msfsIsOpen && !isInstalledAsGitRepo && !isInstalled && !isDownloading && <InstallButton onClick={handleInstall} />}
{!msfsIsOpen && isInstalledAsGitRepo && isInstalled && <InstalledButton inGitRepo={true} />}
{!msfsIsOpen && !isInstalledAsGitRepo && isInstalled && !needsUpdate && !isDownloading && <InstalledButton inGitRepo={false} />}
{!msfsIsOpen && !isInstalledAsGitRepo && needsUpdate && !isDownloading && <UpdateButton onClick={handleUpdate}/>}
{!msfsIsOpen && !isInstalledAsGitRepo && needsUpdate && !isDownloading && <>
<UpdateContainer>
<UpdateReason>{needsUpdateReason}</UpdateReason>
<UpdateButton onClick={handleUpdate} />
</UpdateContainer>
</>}
{isDownloading && <CancelButton onClick={handleCancel}>
{(Math.floor(download?.progress) >= 99) ? "Decompressing" : `${Math.floor(download?.progress)}% - Cancel`}
</CancelButton>}
Expand Down
20 changes: 17 additions & 3 deletions src/renderer/components/AircraftSection/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { Select, Progress } from 'antd';
import styled from 'styled-components';
import { DownloadOutlined } from '@ant-design/icons';
import { dropShadow } from "renderer/style/theme";
import { colors, dropShadow, fontSizes } from "renderer/style/theme";

export const Container = styled.div<{ wait: number }>`
visibility: ${props => props.wait ? 'hidden' : 'visible'};
Expand Down Expand Up @@ -181,12 +181,26 @@ const InstallButtonTemplate = styled(props => <BaseButton
export const InstallButton = styled(props =>
<InstallButtonTemplate
style={{
background: "#fa8c16",
borderColor: "#fa8c16"
background: colors.positive,
borderColor: colors.positive
}}
{...props}
>Install</InstallButtonTemplate>)``;

export const UpdateContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
column-gap: 1.25em;
`;

export const UpdateReason = styled(props => <span className={props.className}>{props.children}</span>)`
font-size: ${fontSizes.huge} !important;
color: ${colors.titleContrast};
`;

export const UpdateButton = styled(
props =>
<InstallButtonTemplate
Expand Down
15 changes: 6 additions & 9 deletions src/renderer/components/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,8 @@ function App() {
url: 'https://flybywiresim-packages.nyc3.cdn.digitaloceanspaces.com/vmaster/A32NX-master.zip',
isExperimental: false,
get latestVersionName() {
return new DataCache<string>('latest_version_dev', RELEASE_CACHE_LIMIT).fetchOrCompute(async () => {
return (await GitVersions.getNewestCommit('flybywiresim', 'a32nx', 'master')).sha.substring(0, 7);
});
return DataCache.from<string>('latest_version_dev', RELEASE_CACHE_LIMIT)
.fetchOrCompute(async () => (await GitVersions.getNewestCommit('flybywiresim', 'a32nx', 'master')).sha.substring(0, 7));
}
},
{
Expand All @@ -149,9 +148,8 @@ function App() {
url: 'https://flybywiresim-packages.nyc3.cdn.digitaloceanspaces.com/stable/A32NX-stable.zip',
isExperimental: false,
get latestVersionName() {
return new DataCache<string>('latest_version_stable', RELEASE_CACHE_LIMIT).fetchOrCompute(async () => {
return (await GitVersions.getReleases('flybywiresim', 'a32nx'))[0].name;
});
return DataCache.from<string>('latest_version_stable', RELEASE_CACHE_LIMIT)
.fetchOrCompute(async () => (await GitVersions.getReleases('flybywiresim', 'a32nx'))[0].name);
},
},
{
Expand All @@ -160,9 +158,8 @@ function App() {
url: 'https://flybywiresim-packages.nyc3.cdn.digitaloceanspaces.com/vmaster-cfbw/A32NX-master-cfbw.zip',
isExperimental: true,
get latestVersionName() {
return new DataCache<string>('latest_version_fbw', RELEASE_CACHE_LIMIT).fetchOrCompute(async () => {
return (await GitVersions.getNewestCommit('flybywiresim', 'a32nx', 'fbw')).sha.substring(0, 7);
});
return DataCache.from<string>('latest_version_fbw', RELEASE_CACHE_LIMIT)
.fetchOrCompute(async () => (await GitVersions.getNewestCommit('flybywiresim', 'a32nx', 'fbw')).sha.substring(0, 7));
},
}
],
Expand Down
44 changes: 1 addition & 43 deletions src/renderer/components/GeneralSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import Store from 'electron-store';
import { setupInstallPath } from 'renderer/actions/install-path.utils';
import { Container, PageTitle, SettingItemContent, SettingItemName, SettingsItem, SettingsItems, SettingButton } from './styles';
import { NXApi } from "@flybywiresim/api-client";

const settings = new Store;

Expand All @@ -23,53 +22,12 @@ function InstallPathSettingItem(): JSX.Element {
);
}

function ApiReleaseSettingItem() {
const [isOnProduction, setIsOnProduction] = useState(true);

useEffect(() => setIsOnProduction(settings.get('mainSettings.apiRelease') === 'true'), []);

function handleClick() {
const isOnProduction = settings.get('mainSettings.apiRelease') === 'production';
settings.set('mainSettings.apiRelease', isOnProduction ? 'staging' : 'production');

NXApi.url = new URL(isOnProduction ? 'https://api.flybywiresim.com' : 'https://api.staging.flybywiresim.com');

setIsOnProduction(isOnProduction);
}

return (
<SettingsItem>
<SettingItemName>API version</SettingItemName>
<SettingButton onClick={handleClick}>{isOnProduction ? 'Production' : 'Staging'}</SettingButton>
</SettingsItem>
);
}

function ClearCacheSettingItem() {
function handleClick() {
for (const key in localStorage) {
if (/data_cache_.+/.test(key)) {
localStorage.removeItem(key);
}
}
}

return (
<SettingsItem>
<SettingItemName>Cache</SettingItemName>
<SettingButton onClick={handleClick}>Clear</SettingButton>
</SettingsItem>
);
}

function index(): JSX.Element {
return (
<Container>
<PageTitle>General Settings</PageTitle>
<SettingsItems>
<InstallPathSettingItem />
<ApiReleaseSettingItem />
<ClearCacheSettingItem />
</SettingsItems>
</Container>
);
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/style/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { css } from "styled-components";

export const fontSizes = {
huge: '20px',
};

export const colors = {
positive: '#00b853',

title: '#FFFFFFDD',
titleContrast: '#FFFFFF',

Expand Down
4 changes: 4 additions & 0 deletions src/renderer/utils/DataCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export class DataCache<T> {
this.limit = limit;
}

static from<T>(key: string, limit: number): DataCache<T> {
return new DataCache(key, limit);
}

async fetchOrCompute(fetcher: () => Promise<T>): Promise<T> {
const cachedData = JSON.parse(localStorage.getItem(`data_cache_${this.key}`));
const cachedDataTimestamp = Number(localStorage.getItem(`data_cache_${this.key}_timestamp`));
Expand Down

0 comments on commit 4fc4f63

Please sign in to comment.