Merge branch 'master' of https://github.com/noisymime/hyper-tuner-cloud
This commit is contained in:
commit
b463809aa6
5
.env
5
.env
|
@ -1,6 +1,11 @@
|
||||||
NPM_GITHUB_TOKEN=
|
NPM_GITHUB_TOKEN=
|
||||||
VITE_ENVIRONMENT=development
|
VITE_ENVIRONMENT=development
|
||||||
|
|
||||||
VITE_WEB_URL=http://localhost:5173
|
VITE_WEB_URL=http://localhost:5173
|
||||||
VITE_SENTRY_DSN=
|
VITE_SENTRY_DSN=
|
||||||
VITE_GTM_ID=
|
VITE_GTM_ID=
|
||||||
VITE_POCKETBASE_API_URL="https://api.hypertuner.cloud"
|
VITE_POCKETBASE_API_URL="https://api.hypertuner.cloud"
|
||||||
|
|
||||||
|
VITE_META_TITLE="HyperTuner Cloud"
|
||||||
|
VITE_META_DESCRIPTION="The best way to share your Speeduino and rusEFI tunes and logs"
|
||||||
|
VITE_META_THEME_COLOR="#191C1E"
|
||||||
|
|
20
README.md
20
README.md
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<p><a href="https://hypertuner.cloud"><strong>hypertuner.cloud</strong></a></p>
|
<p><a href="https://hypertuner.cloud"><strong>hypertuner.cloud</strong></a></p>
|
||||||
<p><sub>The best way to share your tunes and logs</sub></p>
|
<p><sub>The best way to share your tunes and logs.</sub></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -22,8 +22,6 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div align="center"><p>🚧 Work in progress 🚧</p></div>
|
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
![Screenshot VE Table](/public/img/screen1.png)
|
![Screenshot VE Table](/public/img/screen1.png)
|
||||||
|
@ -32,6 +30,10 @@
|
||||||
|
|
||||||
![Screenshot Logs](/public/img/screen2.png)
|
![Screenshot Logs](/public/img/screen2.png)
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
![Screenshot Tooth](/public/img/screen3.png)
|
||||||
|
|
||||||
## Supported ECUs
|
## Supported ECUs
|
||||||
|
|
||||||
### Speeduino
|
### Speeduino
|
||||||
|
@ -39,6 +41,18 @@
|
||||||
- Source code: [noisymime/speeduino](https://github.com/noisymime/speeduino)
|
- Source code: [noisymime/speeduino](https://github.com/noisymime/speeduino)
|
||||||
- Documentation: [wiki.speeduino.com](https://wiki.speeduino.com/)
|
- Documentation: [wiki.speeduino.com](https://wiki.speeduino.com/)
|
||||||
|
|
||||||
|
## Support this project
|
||||||
|
|
||||||
|
[GitHub Sponsors](https://github.com/sponsors/karniv00l)
|
||||||
|
|
||||||
|
## Discord server
|
||||||
|
|
||||||
|
[![HyperTuner Discord server](https://dcbadge.vercel.app/api/server/HdxznPUA)](https://discord.gg/HdxznPUA)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Before you begin please see [Development guide](https://github.com/hyper-tuner/hyper-tuner-cloud/blob/master/DEVELOPMENT.md).
|
Before you begin please see [Development guide](https://github.com/hyper-tuner/hyper-tuner-cloud/blob/master/DEVELOPMENT.md).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](https://github.com/hyper-tuner/hyper-tuner-cloud/blob/master/LICENSE)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -67,6 +67,8 @@
|
||||||
"pocketbase-typegen": "^1.0.11",
|
"pocketbase-typegen": "^1.0.11",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"rollup-plugin-visualizer": "^5.8.3",
|
"rollup-plugin-visualizer": "^5.8.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4",
|
||||||
|
"vite-plugin-html": "^3.2.0",
|
||||||
|
"vite-plugin-pwa": "^0.13.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 106 KiB |
Binary file not shown.
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 140 KiB |
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
|
@ -1,37 +0,0 @@
|
||||||
{
|
|
||||||
"short_name": "HyperTuner Cloud",
|
|
||||||
"name": "HyperTuner Cloud",
|
|
||||||
"description": "The best way to share your Speeduino and rusEFI tunes and logs",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "/icons/icon.ico",
|
|
||||||
"type": "image/x-icon",
|
|
||||||
"sizes": "256x256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/icons/icon.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "512x512"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"screenshots" : [
|
|
||||||
{
|
|
||||||
"src": "/img/screen2.png",
|
|
||||||
"sizes": "1920x1194",
|
|
||||||
"type": "image/png",
|
|
||||||
"platform": "wide",
|
|
||||||
"label": "Log viewer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/img/screen1.png",
|
|
||||||
"sizes": "1920x1194",
|
|
||||||
"type": "image/png",
|
|
||||||
"platform": "wide",
|
|
||||||
"label": "VE Table with command palette"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"theme_color": "#191C1E",
|
|
||||||
"background_color": "#191C1E"
|
|
||||||
}
|
|
|
@ -62,6 +62,7 @@ const ResetPassword = lazy(() => import('./pages/auth/ResetPassword'));
|
||||||
const ResetPasswordConfirmation = lazy(() => import('./pages/auth/ResetPasswordConfirmation'));
|
const ResetPasswordConfirmation = lazy(() => import('./pages/auth/ResetPasswordConfirmation'));
|
||||||
const EmailVerification = lazy(() => import('./pages/auth/EmailVerification'));
|
const EmailVerification = lazy(() => import('./pages/auth/EmailVerification'));
|
||||||
const OauthCallback = lazy(() => import('./pages/auth/OauthCallback'));
|
const OauthCallback = lazy(() => import('./pages/auth/OauthCallback'));
|
||||||
|
const About = lazy(() => import('./pages/About'));
|
||||||
|
|
||||||
const { Content } = Layout;
|
const { Content } = Layout;
|
||||||
|
|
||||||
|
@ -200,6 +201,7 @@ const App = ({ ui, tuneData }: { ui: UIState, tuneData: TuneDataState }) => {
|
||||||
<Route path={Routes.SIGN_UP} element={<ContentFor element={<Login formRole={FormRoles.SING_UP} />} />} />
|
<Route path={Routes.SIGN_UP} element={<ContentFor element={<Login formRole={FormRoles.SING_UP} />} />} />
|
||||||
<Route path={Routes.PROFILE} element={<ContentFor element={<Profile />} />} />
|
<Route path={Routes.PROFILE} element={<ContentFor element={<Profile />} />} />
|
||||||
<Route path={Routes.RESET_PASSWORD} element={<ContentFor element={<ResetPassword />} />} />
|
<Route path={Routes.RESET_PASSWORD} element={<ContentFor element={<ResetPassword />} />} />
|
||||||
|
<Route path={Routes.ABOUT} element={<ContentFor element={<About />} />} />
|
||||||
|
|
||||||
<Route path={Routes.EMAIL_VERIFICATION} element={<ContentFor element={<EmailVerification />} />} />
|
<Route path={Routes.EMAIL_VERIFICATION} element={<ContentFor element={<EmailVerification />} />} />
|
||||||
<Route path={Routes.RESET_PASSWORD_CONFIRMATION} element={<ContentFor element={<ResetPasswordConfirmation />} />} />
|
<Route path={Routes.RESET_PASSWORD_CONFIRMATION} element={<ContentFor element={<ResetPasswordConfirmation />} />} />
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -2,6 +2,7 @@ import {
|
||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Layout,
|
Layout,
|
||||||
Space,
|
Space,
|
||||||
|
@ -18,6 +19,7 @@ import {
|
||||||
AppState,
|
AppState,
|
||||||
TuneState,
|
TuneState,
|
||||||
} from '../types/state';
|
} from '../types/state';
|
||||||
|
import { Routes } from '../routes';
|
||||||
|
|
||||||
const { Footer } = Layout;
|
const { Footer } = Layout;
|
||||||
|
|
||||||
|
@ -55,16 +57,12 @@ const StatusBar = ({ tune }: { tune: TuneState }) => (
|
||||||
{tune?.details?.author && <Firmware tune={tune} />}
|
{tune?.details?.author && <Firmware tune={tune} />}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={4} style={{ textAlign: 'right' }}>
|
<Col span={4} style={{ textAlign: 'right' }}>
|
||||||
<a
|
<Link to={Routes.ABOUT}>
|
||||||
href="https://github.com/hyper-tuner/hyper-tuner-cloud"
|
<Space>
|
||||||
target="__blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<Space className="github-link">
|
|
||||||
<GithubOutlined />
|
<GithubOutlined />
|
||||||
GitHub
|
GitHub
|
||||||
</Space>
|
</Space>
|
||||||
</a>
|
</Link>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Footer>
|
</Footer>
|
||||||
|
|
|
@ -226,7 +226,7 @@ const TopBar = ({
|
||||||
return list.length ? list : null;
|
return list.length ? list : null;
|
||||||
}, [lg, sm]);
|
}, [lg, sm]);
|
||||||
|
|
||||||
const userMenuItems = useMemo(() => currentUser ? [{
|
const userAuthMenuItems = useMemo(() => currentUser ? [{
|
||||||
key: 'profile',
|
key: 'profile',
|
||||||
icon: <UserOutlined />,
|
icon: <UserOutlined />,
|
||||||
label: 'Profile',
|
label: 'Profile',
|
||||||
|
@ -248,6 +248,20 @@ const TopBar = ({
|
||||||
onClick: () => navigate(Routes.SIGN_UP),
|
onClick: () => navigate(Routes.SIGN_UP),
|
||||||
}], [currentUser, logoutClick, navigate]);
|
}], [currentUser, logoutClick, navigate]);
|
||||||
|
|
||||||
|
const userMenuItems = [
|
||||||
|
...userAuthMenuItems,
|
||||||
|
{
|
||||||
|
key: 'divider',
|
||||||
|
type: 'divider',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'about',
|
||||||
|
icon: <InfoCircleOutlined />,
|
||||||
|
label: 'About',
|
||||||
|
onClick: () => navigate(Routes.ABOUT),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Header className="app-top-bar" style={xs ? { padding: '0 5px' } : {}}>
|
<Header className="app-top-bar" style={xs ? { padding: '0 5px' } : {}}>
|
||||||
<Row>
|
<Row>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background-color: @main-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
|
@ -46,10 +47,6 @@ html, body {
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.github-link {
|
|
||||||
animation: wiggle 2s linear 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-sidebar {
|
.app-sidebar {
|
||||||
|
@ -194,3 +191,7 @@ select:-webkit-autofill:focus {
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sponsor-button {
|
||||||
|
animation: wiggle 2s linear 1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Result,
|
||||||
|
} from 'antd';
|
||||||
|
import {
|
||||||
|
HeartOutlined,
|
||||||
|
GithubOutlined,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import hyperIcon from '../assets/img/hyper-tuner-logo.png';
|
||||||
|
|
||||||
|
const About = () => (
|
||||||
|
<div className="large-container">
|
||||||
|
<Result
|
||||||
|
status="success"
|
||||||
|
icon={<img src={hyperIcon} alt="HyperTuner" style={{ maxWidth: 100 }} />}
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
Powered by <a href="https://github.com/hyper-tuner" target="_blank" rel="noreferrer">HyperTuner</a>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
<>
|
||||||
|
Created with <HeartOutlined /> by <a href="https://github.com/karniv00l" target="_blank" rel="noreferrer">Piotr Rogowski</a>,
|
||||||
|
licensed under <a href="https://github.com/hyper-tuner/hyper-tuner-cloud/blob/master/LICENSE" target="_blank" rel="noreferrer">MIT</a>.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
extra={[
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
key="sponsor"
|
||||||
|
className="sponsor-button"
|
||||||
|
icon={<HeartOutlined />}
|
||||||
|
onClick={() => window.open('https://github.com/sponsors/karniv00l', '_blank')}
|
||||||
|
>
|
||||||
|
Sponsor
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="source"
|
||||||
|
icon={<GithubOutlined />}
|
||||||
|
onClick={() => window.open('https://github.com/hyper-tuner/hyper-tuner-cloud', '_blank')}
|
||||||
|
>
|
||||||
|
Source
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default About;
|
|
@ -25,5 +25,7 @@ export enum Routes {
|
||||||
EMAIL_VERIFICATION = '/auth/email-verification/:token',
|
EMAIL_VERIFICATION = '/auth/email-verification/:token',
|
||||||
OAUTH_CALLBACK = '/auth/oauth-callback/:provider',
|
OAUTH_CALLBACK = '/auth/oauth-callback/:provider',
|
||||||
|
|
||||||
|
ABOUT = '/about',
|
||||||
|
|
||||||
REDIRECT_PAGE_OAUTH_CALLBACK = 'oauth',
|
REDIRECT_PAGE_OAUTH_CALLBACK = 'oauth',
|
||||||
}
|
}
|
||||||
|
|
134
vite.config.ts
134
vite.config.ts
|
@ -1,40 +1,108 @@
|
||||||
import { defineConfig } from 'vite';
|
import {
|
||||||
|
defineConfig,
|
||||||
|
loadEnv,
|
||||||
|
} from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
export default ({ mode }) => {
|
||||||
export default defineConfig({
|
const env = loadEnv(mode, process.cwd());
|
||||||
build: {
|
|
||||||
outDir: 'build',
|
return defineConfig({
|
||||||
sourcemap: true,
|
build: {
|
||||||
rollupOptions: {
|
outDir: 'build',
|
||||||
output: {
|
sourcemap: true,
|
||||||
manualChunks: {
|
rollupOptions: {
|
||||||
react: ['react', 'react-dom'],
|
output: {
|
||||||
antdResult: ['antd/es/result'],
|
manualChunks: {
|
||||||
antdTable: ['antd/es/table'],
|
react: ['react', 'react-dom'],
|
||||||
antdIcons: ['@ant-design/icons'],
|
antdResult: ['antd/es/result'],
|
||||||
uplot: ['uplot'],
|
antdTable: ['antd/es/table'],
|
||||||
sentry: ['@sentry/react', '@sentry/browser', '@sentry/tracing'],
|
antdIcons: ['@ant-design/icons'],
|
||||||
kbar: ['kbar'],
|
uplot: ['uplot'],
|
||||||
perfectScrollbar: ['perfect-scrollbar'],
|
sentry: ['@sentry/react', '@sentry/browser', '@sentry/tracing'],
|
||||||
pako: ['pako'],
|
kbar: ['kbar'],
|
||||||
mlgConverter: ['mlg-converter'],
|
perfectScrollbar: ['perfect-scrollbar'],
|
||||||
|
pako: ['pako'],
|
||||||
|
mlgConverter: ['mlg-converter'],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
server: {
|
||||||
server: {
|
open: true,
|
||||||
open: true,
|
host: '0.0.0.0',
|
||||||
host: '0.0.0.0',
|
|
||||||
},
|
|
||||||
css: {
|
|
||||||
preprocessorOptions: {
|
|
||||||
less: { javascriptEnabled: true },
|
|
||||||
},
|
},
|
||||||
},
|
css: {
|
||||||
plugins: [
|
preprocessorOptions: {
|
||||||
react(),
|
less: { javascriptEnabled: true },
|
||||||
visualizer(),
|
},
|
||||||
],
|
},
|
||||||
});
|
plugins: [
|
||||||
|
react(),
|
||||||
|
visualizer(),
|
||||||
|
createHtmlPlugin({
|
||||||
|
template: '/index.html',
|
||||||
|
inject: {
|
||||||
|
data: {
|
||||||
|
metaTitle: env.VITE_META_TITLE,
|
||||||
|
metaDescription: env.VITE_META_DESCRIPTION,
|
||||||
|
metaImage: `${env.VITE_WEB_URL}/img/screen2.png`,
|
||||||
|
metaUrl: env.VITE_WEB_URL,
|
||||||
|
metaThemeColor: env.VITE_META_THEME_COLOR,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
VitePWA({
|
||||||
|
registerType: null,
|
||||||
|
devOptions: { enabled: true },
|
||||||
|
manifest: {
|
||||||
|
name: env.VITE_META_TITLE,
|
||||||
|
short_name: env.VITE_META_TITLE,
|
||||||
|
description: env.VITE_META_DESCRIPTION,
|
||||||
|
start_url: '.',
|
||||||
|
display: 'standalone',
|
||||||
|
theme_color: env.VITE_META_THEME_COLOR,
|
||||||
|
background_color: env.VITE_META_THEME_COLOR,
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: '/icons/icon.ico',
|
||||||
|
type: 'image/x-icon',
|
||||||
|
sizes: '256x256',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: '/icons/icon.png',
|
||||||
|
type: 'image/png',
|
||||||
|
sizes: '512x512',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
screenshots: [
|
||||||
|
{
|
||||||
|
src: '/img/screen1.png',
|
||||||
|
sizes: '3008x2050',
|
||||||
|
type: 'image/png',
|
||||||
|
platform: 'wide',
|
||||||
|
label: 'Tune view',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: '/img/screen2.png',
|
||||||
|
sizes: '3008x2050',
|
||||||
|
type: 'image/png',
|
||||||
|
platform: 'wide',
|
||||||
|
label: 'Log viewer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: '/img/screen3.png',
|
||||||
|
sizes: '3008x2050',
|
||||||
|
type: 'image/png',
|
||||||
|
platform: 'wide',
|
||||||
|
label: 'Tooth log viewer',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue