mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-02-05 23:32:48 -08:00
refactor: new About page
This commit is contained in:
parent
7bcb5b5b34
commit
7a8aff80c4
10 changed files with 162 additions and 122 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"Asyncify",
|
||||
"dugite",
|
||||
"fullscreenable",
|
||||
"maximizable",
|
||||
|
|
|
|||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -14892,6 +14892,12 @@
|
|||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"react-async": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-async/-/react-async-10.0.1.tgz",
|
||||
"integrity": "sha512-ORUz5ca0B57QgBIzEZM5SuhJ6xFjkvEEs0gylLNlWf06vuVcLZsjIw3wx58jJkZG38p+0nUAxRgFW2b7mnVZzA==",
|
||||
"dev": true
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@
|
|||
"prop-types": "15.7.2",
|
||||
"react": "17.0.1",
|
||||
"react-ace": "9.2.1",
|
||||
"react-async": "^10.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-i18next": "^11.8.5",
|
||||
"react-redux": "7.2.2",
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
import React from 'react';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import connectComponent from '../../helpers/connect-component';
|
||||
|
||||
const styles = (theme: any) => ({
|
||||
icon: {
|
||||
height: 96,
|
||||
width: 96,
|
||||
},
|
||||
dialogContent: {
|
||||
minWidth: 320,
|
||||
textAlign: 'center',
|
||||
},
|
||||
title: {
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
version: {
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
versionSmallContainer: {
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
versionSmall: {
|
||||
fontSize: '0.8rem',
|
||||
},
|
||||
goToTheWebsiteButton: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
madeBy: {
|
||||
marginTop: theme.spacing(2),
|
||||
},
|
||||
link: {
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
},
|
||||
});
|
||||
interface AboutProps {
|
||||
classes: any;
|
||||
}
|
||||
const About = (props: AboutProps) => {
|
||||
const { classes } = props;
|
||||
const versions = [
|
||||
{ name: 'Electron Version', version: window.remote.getEnvironmentVersions().electron },
|
||||
{ name: 'Node Version', version: window.remote.getEnvironmentVersions().node },
|
||||
{ name: 'Chromium Version', version: window.remote.getEnvironmentVersions().chrome },
|
||||
];
|
||||
return (
|
||||
<div>
|
||||
<DialogContent className={classes.dialogContent}>
|
||||
<img src={`file:///${(window.meta as any).iconPath}`} alt="TiddlyGit" className={classes.icon} />
|
||||
<Typography variant="h6" className={classes.title}>
|
||||
TiddlyGit
|
||||
</Typography>
|
||||
<Typography variant="body2" className={classes.version}>
|
||||
{`Version v${window.remote.getAppVersion()}.`}
|
||||
</Typography>
|
||||
<div className={classes.versionSmallContainer}>
|
||||
{versions.map(({ name, version }) => (
|
||||
<Typography key={name} variant="body2" className={classes.versionSmall}>
|
||||
{name}: {version}
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button onClick={async () => await window.service.native.open('https://github.com/tiddly-gittly/TiddlyGit-Desktop')}>Website</Button>
|
||||
<br />
|
||||
<Button onClick={async () => await window.service.native.open('https://github.com/tiddly-gittly/TiddlyGit-Desktop/issues/new/choose')}>Support</Button>
|
||||
|
||||
<Typography variant="body2" className={classes.madeBy}>
|
||||
<span>Made with </span>
|
||||
<span role="img" aria-label="love">
|
||||
❤
|
||||
</span>
|
||||
<span> by </span>
|
||||
<span
|
||||
onClick={async () => await window.service.native.open('https://onetwo.ren/wiki/')}
|
||||
onKeyDown={async (event) => {
|
||||
if (event.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
await window.service.native.open('https://onetwo.ren/wiki/');
|
||||
}}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
className={classes.link}>
|
||||
Lin Onetwo
|
||||
</span>
|
||||
<span> and </span>
|
||||
<span
|
||||
onClick={async () => await window.service.native.open('https://webcatalog.app/?utm_source=tiddlygit_app')}
|
||||
onKeyDown={async (event) => {
|
||||
if (event.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
await window.service.native.open('https://webcatalog.app/?utm_source=tiddlygit_app');
|
||||
}}
|
||||
role="link"
|
||||
tabIndex={0}
|
||||
className={classes.link}>
|
||||
WebCatalog
|
||||
</span>
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default connectComponent(About, null, null, styles);
|
||||
18
src/helpers/use-service-value.ts
Normal file
18
src/helpers/use-service-value.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
/**
|
||||
* Use value from service, especially constant value that never changes
|
||||
* This will only update once, won't listen on later update.
|
||||
* @param valuePromise A promise contain the value we want to use in React
|
||||
* @param defaultValue empty array or undefined, as initial value
|
||||
*/
|
||||
export function usePromiseValue<T>(valuePromise: Promise<T> | (() => Promise<T>), defaultValue?: T): T | undefined {
|
||||
const [value, valueSetter] = useState<T | undefined>(defaultValue);
|
||||
useEffect(() => {
|
||||
void (async () => {
|
||||
valueSetter(typeof valuePromise === 'function' ? await valuePromise() : await valuePromise);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return value;
|
||||
}
|
||||
119
src/pages/About.tsx
Normal file
119
src/pages/About.tsx
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, DialogContent } from '@material-ui/core';
|
||||
import { usePromiseValue } from '@/helpers/use-service-value';
|
||||
|
||||
const Icon = styled.img`
|
||||
height: 96;
|
||||
width: 96;
|
||||
`;
|
||||
|
||||
const DialogContentSC = styled(DialogContent)`
|
||||
min-width: 320;
|
||||
text-align: 'center';
|
||||
`;
|
||||
|
||||
const Title = styled.h6`
|
||||
margin-top: 10px;
|
||||
`;
|
||||
|
||||
const Version = styled.p`
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const VersionSmallContainer = styled.div`
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const VersionSmall = styled.span`
|
||||
font-size: 0.8rem;
|
||||
`;
|
||||
|
||||
const GoToTheWebsiteButton = styled(Button)`
|
||||
margin-right: 10px;
|
||||
`;
|
||||
|
||||
const MadeBy = styled.div`
|
||||
margin-top: 20px;
|
||||
`;
|
||||
|
||||
const Link = styled.span`
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function About(): JSX.Element {
|
||||
const versions = usePromiseValue(async () => {
|
||||
const processVersions = (await window.service.context.get('environmentVersions')) as NodeJS.ProcessVersions;
|
||||
return [
|
||||
{ name: 'Electron Version', version: processVersions.electron },
|
||||
{ name: 'Node Version', version: processVersions.node },
|
||||
{ name: 'Chromium Version', version: processVersions.chrome },
|
||||
];
|
||||
}, []);
|
||||
|
||||
const iconPath = usePromiseValue<string | undefined>(window.service.context.get('ICON_PATH') as Promise<string>);
|
||||
const appVersion = usePromiseValue<string | undefined>(window.service.context.get('appVersion') as Promise<string>);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DialogContentSC>
|
||||
<Icon src={iconPath} alt="TiddlyGit" />
|
||||
<Title>TiddlyGit</Title>
|
||||
<Version>{`Version v${appVersion ?? ' - '}.`}</Version>
|
||||
<VersionSmallContainer>
|
||||
{versions?.map(({ name, version }) => (
|
||||
<VersionSmall key={name}>
|
||||
{name}: {version}
|
||||
</VersionSmall>
|
||||
))}
|
||||
</VersionSmallContainer>
|
||||
|
||||
<GoToTheWebsiteButton onClick={async () => await window.service.native.open('https://github.com/tiddly-gittly/TiddlyGit-Desktop')}>
|
||||
Website
|
||||
</GoToTheWebsiteButton>
|
||||
<br />
|
||||
<GoToTheWebsiteButton onClick={async () => await window.service.native.open('https://github.com/tiddly-gittly/TiddlyGit-Desktop/issues/new/choose')}>
|
||||
Support
|
||||
</GoToTheWebsiteButton>
|
||||
|
||||
<MadeBy>
|
||||
<span>Made with </span>
|
||||
<span role="img" aria-label="love">
|
||||
❤
|
||||
</span>
|
||||
<span> by </span>
|
||||
<Link
|
||||
onClick={async () => await window.service.native.open('https://onetwo.ren/wiki/')}
|
||||
onKeyDown={async (event) => {
|
||||
if (event.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
await window.service.native.open('https://onetwo.ren/wiki/');
|
||||
}}
|
||||
role="link"
|
||||
tabIndex={0}>
|
||||
Lin Onetwo
|
||||
</Link>
|
||||
<span> and </span>
|
||||
<Link
|
||||
onClick={async () => await window.service.native.open('https://webcatalog.app/?utm_source=tiddlygit_app')}
|
||||
onKeyDown={async (event) => {
|
||||
if (event.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
await window.service.native.open('https://webcatalog.app/?utm_source=tiddlygit_app');
|
||||
}}
|
||||
role="link"
|
||||
tabIndex={0}>
|
||||
WebCatalog
|
||||
</Link>
|
||||
</MadeBy>
|
||||
</DialogContentSC>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -12,11 +12,6 @@ import { Channels } from '@/constants/channels';
|
|||
// ipcRenderer.once(channel, listener);
|
||||
// },
|
||||
// },
|
||||
// getPlatform: () => remote.process.platform,
|
||||
// getAppVersion: () => remote.app.getVersion(),
|
||||
// getAppName: () => remote.app.name,
|
||||
// getOSVersion: () => remote.require('os').release(),
|
||||
// getEnvironmentVersions: () => process.versions,
|
||||
// getGlobal: (key: any) => remote.getGlobal(key),
|
||||
// useCurrentWindow: (callback: any) => callback(remote.getCurrentWindow()),
|
||||
// getCurrentWindowID: () => remote.getCurrentWindow().id,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { initI18N } from './i18n';
|
|||
|
||||
import AppWrapper from './components/app-wrapper';
|
||||
|
||||
const DialogAbout = React.lazy(async () => await import('./components/dialog-about'));
|
||||
const AboutPage = React.lazy(async () => await import('./pages/About'));
|
||||
const DialogAddWorkspace = React.lazy(async () => await import('./components/dialog-add-workspace'));
|
||||
const DialogAuth = React.lazy(async () => await import('./components/dialog-auth'));
|
||||
const DialogCodeInjection = React.lazy(async () => await import('./components/dialog-code-injection'));
|
||||
|
|
@ -41,7 +41,7 @@ const App = (): JSX.Element => {
|
|||
switch (window.meta.windowName) {
|
||||
case WindowNames.about:
|
||||
document.title = 'About';
|
||||
return <DialogAbout />;
|
||||
return <AboutPage />;
|
||||
case WindowNames.addWorkspace:
|
||||
document.title = 'Add Workspace';
|
||||
return <DialogAddWorkspace />;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { injectable } from 'inversify';
|
||||
import { app } from 'electron';
|
||||
import process from 'process';
|
||||
import os from 'os';
|
||||
import isDevelopment from 'electron-is-dev';
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
import { IContextService, IContext, IPaths, IConstants } from './interface';
|
||||
import * as paths from '@services/constants/paths';
|
||||
|
|
@ -9,6 +12,11 @@ export class ContextService implements IContextService {
|
|||
pathConstants: IPaths = paths;
|
||||
constants: IConstants = {
|
||||
isDevelopment,
|
||||
platform: process.platform,
|
||||
appVersion: app.getVersion(),
|
||||
appName: app.name,
|
||||
oSVersion: os.release(),
|
||||
environmentVersions: process.versions,
|
||||
};
|
||||
|
||||
public get<K extends keyof IContext>(key: K): IContext[K] {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,14 @@ export interface IPaths {
|
|||
*/
|
||||
export interface IConstants {
|
||||
isDevelopment: boolean;
|
||||
platform: string;
|
||||
appVersion: string;
|
||||
appName: string;
|
||||
oSVersion: string;
|
||||
environmentVersions: NodeJS.ProcessVersions;
|
||||
}
|
||||
|
||||
export type IContext = IPaths | IConstants;
|
||||
export interface IContext extends IPaths, IConstants {}
|
||||
|
||||
/**
|
||||
* Manage constant value like `isDevelopment` and many else, so you can know about about running environment in main and renderer process easily.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue