This commit is contained in:
Felix Zedén Yverås 2024-08-04 14:08:27 +00:00 committed by GitHub
commit 8a7805cdde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 2906 additions and 193 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
dist
dist-ssr
dev-dist
*.local
# Editor directories and files

View File

@ -5,7 +5,12 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32">
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16">
<meta name="theme-color" content="#14475b" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#14475b" media="(prefers-color-scheme: dark)">
<meta
name="description"
content="Online database entity-realtionship diagram editor, data modeler, and SQL generator. Design, visualize, and export scripts without an account and completely free of charge."
@ -35,7 +40,6 @@
/>
<meta name="twitter:card" content="summary_large_image" />
<link rel="apple-touch-icon" href="/favicon.ico" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css"

2966
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -52,7 +52,9 @@
"postcss": "^8.4.32",
"prettier": "3.2.5",
"tailwindcss": "^3.3.6",
"vite": "^5.0.11"
"vite": "^5.0.11",
"vite-plugin-pwa": "^0.20.0",
"workbox-window": "^7.1.0"
},
"overrides": {
"follow-redirects": "^1.15.4"

BIN
public/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

BIN
public/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
public/pwa-192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/pwa-512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -9,6 +9,7 @@ import LandingPage from "./pages/LandingPage";
import SettingsContextProvider from "./context/SettingsContext";
import { useSettings } from "./hooks";
import NotFound from "./pages/NotFound";
import { PwaUpdatePrompt } from "./components/PwaUpdatePrompt";
export default function App() {
return (
@ -53,6 +54,7 @@ export default function App() {
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
<PwaUpdatePrompt />
</SettingsContextProvider>
);
}

View File

@ -1,6 +1,8 @@
import { useState } from "react";
import { useRegisterSW } from "virtual:pwa-register/react";
import {
IconCaretdown,
IconCloud,
IconChevronRight,
IconChevronUp,
IconChevronDown,
@ -18,6 +20,7 @@ import {
InputNumber,
Tooltip,
Spin,
Tag,
Toast,
Popconfirm,
} from "@douyinfe/semi-ui";
@ -1351,9 +1354,13 @@ export default function ControlPanel({
});
useHotkeys("ctrl+alt+w, meta+alt+w", fitWindow, { preventDefault: true });
const {
offlineReady: [isOfflineReady],
} = useRegisterSW();
return (
<>
{layout.header && header()}
{layout.header && header(isOfflineReady)}
{layout.toolbar && toolbar()}
<Modal
modal={modal}
@ -1560,10 +1567,10 @@ export default function ControlPanel({
}
}
function header() {
function header(isOfflineReady) {
return (
<nav className="flex justify-between pt-1 items-center whitespace-nowrap">
<div className="flex justify-start items-center">
<div className="flex justify-start items-center grow">
<Link to="/">
<img
width={54}
@ -1572,7 +1579,7 @@ export default function ControlPanel({
className="ms-8 min-w-[54px]"
/>
</Link>
<div className="ms-1 mt-1">
<div className="ms-1 sm:me-1 xl:me-6 mt-1 grow">
<div className="flex items-center ms-3 gap-2">
{databases[database].image && (
<img
@ -1602,7 +1609,7 @@ export default function ControlPanel({
</div>
{(showEditName || modal === MODAL.RENAME) && <IconEdit />}
</div>
<div className="flex justify-between items-center">
<div className="flex justify-start items-center">
<div className="flex justify-start text-md select-none me-2">
{Object.keys(menu).map((category) => (
<Dropdown
@ -1709,6 +1716,13 @@ export default function ControlPanel({
>
{getState()}
</Button>
{isOfflineReady && (
<span className="ms-auto">
<Tag prefixIcon={<IconCloud />} size="large">
{t("available_offline")}
</Tag>
</span>
)}
</div>
</div>
</div>

View File

@ -0,0 +1,34 @@
import { useRegisterSW } from "virtual:pwa-register/react";
import { Typography, Toast } from "@douyinfe/semi-ui";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
const { Text } = Typography;
export function PwaUpdatePrompt() {
const { t } = useTranslation();
const {
needRefresh: [isRefreshNeeded],
updateServiceWorker,
} = useRegisterSW();
useEffect(() => {
if (!isRefreshNeeded) return;
Toast.info({
duration: 0, // indefinite
content: (
<div>
<h5>{t("update_available")}</h5>
<p className="text-xs">{t("reload_page_to_update")}</p>
<div className="mt-2">
<Text link onClick={updateServiceWorker}>
{t("reload_now")}
</Text>
</div>
</div>
),
});
}, [isRefreshNeeded, updateServiceWorker, t]);
return <></>;
}

View File

@ -6,6 +6,10 @@ const english = {
const en = {
translation: {
available_offline: "Available offline",
update_available: "An updated version of drawDB is available!",
reload_page_to_update: "Reload the page to update",
reload_now: "Reload now",
report_bug: "Report a bug",
import: "Import",
file: "File",

View File

@ -1,7 +1,55 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})
plugins: [
react(),
VitePWA({
workbox: {
globPatterns: ["**/*"],
maximumFileSizeToCacheInBytes: 15_000_000,
},
includeAssets: ["**/*"],
registerType: "prompt",
manifest: {
name: "DrawDB",
short_name: "DrawDB",
icons: [
{
src: "/pwa-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "any",
},
{
src: "/pwa-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any",
},
{
src: "/pwa-maskable-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "maskable",
},
{
src: "/pwa-maskable-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
scope: "/",
start_url: "/editor",
display: "standalone",
background_color: "#14475b",
theme_color: "#14475b",
description:
"Free, simple, and intuitive database design tool and SQL generator.",
},
}),
],
});