dev/mobile
Lei OT 1 year ago
parent 537e1f570f
commit 50b242cb27

@ -20,6 +20,7 @@
"react-router-dom": "^6.21.1", "react-router-dom": "^6.21.1",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"vite-plugin-pwa": "^0.19.6",
"zustand": "^4.5.0" "zustand": "^4.5.0"
}, },
"devDependencies": { "devDependencies": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -8,6 +8,7 @@ import 'dayjs/locale/zh-cn'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Outlet, useHref, useNavigate } from 'react-router-dom' import { Outlet, useHref, useNavigate } from 'react-router-dom'
import AppLogo from '@/assets/logo-gh.png'
import '@/assets/App.css' import '@/assets/App.css'
import 'react-chat-elements/dist/main.css' import 'react-chat-elements/dist/main.css'
@ -20,12 +21,33 @@ function AuthApp() {
const href = useHref() const href = useHref()
// Whether we are running as an installed PWA or not.
const isInstalledPWA = window.matchMedia('(display-mode: window-controls-overlay)').matches ||
window.matchMedia('(display-mode: standalone)').matches;
const [connectWebsocket, fetchInitialData, disconnectWebsocket ] = useConversationStore((state) => [ const [connectWebsocket, fetchInitialData, disconnectWebsocket ] = useConversationStore((state) => [
state.connectWebsocket, state.connectWebsocket,
state.fetchInitialData, state.fetchInitialData,
state.disconnectWebsocket, state.disconnectWebsocket,
]); ]);
useEffect(() => { useEffect(() => {
if (! isInstalledPWA) {
document.getElementById('about-dialog').showModal();
}
if (!isInstalledPWA ) {
window.addEventListener('beforeinstallprompt', e => {
// Don't let the default prompt go.
e.preventDefault();
// Instead, wait for the user to click the install button.
document.getElementById('about-dialog').addEventListener('close', () => {
if (document.getElementById('about-dialog').returnValue === "install") {
e.prompt();
}
});
});
} else {
document.getElementById('install-button').disabled = true;
}
if (!("Notification" in window)) { if (!("Notification" in window)) {
alert("This browser does not support desktop notification"); alert("This browser does not support desktop notification");
} else { } else {
@ -57,20 +79,34 @@ function AuthApp() {
token: { token: {
colorPrimary: colorPrimary, colorPrimary: colorPrimary,
borderRadius: borderRadius, borderRadius: borderRadius,
fontFamily: "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Noto Color Emoji','Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'", fontFamily:
"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Noto Color Emoji','Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'",
}, },
algorithm: theme.defaultAlgorithm, algorithm: theme.defaultAlgorithm,
}} }}
locale={zhLocale} locale={zhLocale}
renderEmpty={() => <Empty description={false} />} renderEmpty={() => <Empty description={false} />}>
>
<AntApp> <AntApp>
<ErrorBoundary> <ErrorBoundary>
<Outlet /> <Outlet />
<dialog id='about-dialog' className='border-0'>
<img className='logo' src={AppLogo} alt='logo' />
<section className='about'>
<h1>销售平台</h1>
<h2>Sales CRM</h2>
<p>Haina travel global sales CRM system</p>
</section>
<form className='actions flex gap-1' method='dialog'>
<button value='cancel' className='px-4 py-2 rounded-full border-0'>Close</button>
<button value='install' id='install-button' className='px-4 py-2 rounded-full border-0 border-transparent bg-indigo-500 text-white'>
Install app
</button>
</form>
</dialog>
</ErrorBoundary> </ErrorBoundary>
</AntApp> </AntApp>
</ConfigProvider> </ConfigProvider>
) );
} }
export default AuthApp export default AuthApp

@ -1,31 +1,72 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react';
import WindiCSS from 'vite-plugin-windicss' import WindiCSS from 'vite-plugin-windicss';
import { VitePWA } from 'vite-plugin-pwa';
const buildDatePlugin = () => { const buildDatePlugin = () => {
return { return {
transformIndexHtml(html) { transformIndexHtml(html) {
const dataString = new Date().toISOString() const dataString = new Date().toISOString();
return html.replace( return html.replace(/%BUILD_DATE%/, `${dataString}`);
/%BUILD_DATE%/,
`${dataString}`,
)
}, },
} };
} };
// PWA plugin
const manifestForPlugIn = {
registerType: 'prompt',
// includeAssests: ['/src/assets/logo-gh.png'],
// registerType: 'autoUpdate',
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
},
manifest: {
name: 'Sales CRM',
short_name: 'Sales CRM',
description: 'Haina travel global sales CRM system',
icons: [
{
src: '/favicon.ico',
sizes: '32x32',
},
{
src: '/s-launchericon-192-192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/s-launchericon-144-144.png',
sizes: '144x144',
type: 'image/png',
},
{
src: '/s-launchericon-512-512.png',
sizes: '512x512',
type: 'image/png',
},
],
theme_color: '#171717',
background_color: '#ccd5ae',
display: 'standalone',
display_override: ['window-controls-overlay'],
scope: '/',
start_url: '.',
orientation: 'portrait',
},
};
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react(), WindiCSS(), buildDatePlugin()], plugins: [react(), WindiCSS(), buildDatePlugin(), VitePWA(manifestForPlugIn)],
server: { server: {
host: "0.0.0.0", host: '0.0.0.0',
}, },
resolve: { resolve: {
alias: { alias: {
"@": "/src", '@': '/src',
}, },
}, },
build: { build: {
// outDir: 'distTTT',
emptyOutDir: true,
sourcemap: true, sourcemap: true,
manifest: true, manifest: true,
chunkSizeWarningLimit: 555, chunkSizeWarningLimit: 555,
@ -44,6 +85,6 @@ export default defineConfig({
// } // }
}, },
terserOptions: { terserOptions: {
maxWorkers: 4 maxWorkers: 4,
} },
}) });

Loading…
Cancel
Save