Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(console): Improve UX by preventing screen flickering #133

Merged
merged 2 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.14.10",
"@tanstack/solid-form": "^0.34.0",
"@tanstack/solid-query": "^5.66.4",
"@tanstack/solid-table": "^8.20.5",
"@tanstack/valibot-form-adapter": "^0.34.0",
"@types/node": "^22.8.6",
Expand Down
34 changes: 20 additions & 14 deletions packages/console/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { MetaProvider, Title } from "@solidjs/meta";
import { Route, Router } from "@solidjs/router";
import { Suspense } from "solid-js";
import "./App.css";
import { Toaster } from "./components/ui/sonner";
import { SplashScreen } from "@/components/spash-screen";
import Layout from "@/components/ui/layout";
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query";
import { Suspense } from "solid-js";
import Home from "./routes";
const queryClient = new QueryClient();

export default function App() {
return (
<Router
root={(props) => (
<MetaProvider>
<Title>HotUpdater Console</Title>
<Suspense>{props.children}</Suspense>
<Toaster />
</MetaProvider>
)}
>
<Route path="/" component={Home} />
<Route path="/:bundleId" component={Home} />
</Router>
<QueryClientProvider client={queryClient}>
<Router
root={(props) => (
<MetaProvider>
<Title>HotUpdater Console</Title>
<Suspense fallback={<SplashScreen />}>
<Layout>{props.children}</Layout>
</Suspense>
</MetaProvider>
)}
>
<Route path="/" component={Home} />
<Route path="/:bundleId" component={Home} />
</Router>
</QueryClientProvider>
);
}
21 changes: 21 additions & 0 deletions packages/console/src/components/ui/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import logo from "@/assets/logo.png";
import type { JSX } from "solid-js";

export default function Layout({ children }: { children: JSX.Element }) {
return (
<main class="w-full space-y-2.5">
<div class="flex flex-row items-center gap-1">
<img src={logo} alt="Hot Updater Console" class="w-12 h-12" />
<a
href="https://github.com/gronxb/hot-updater"
target="_blank"
class="text-2xl font-light"
rel="noreferrer"
>
Hot Updater Console
</a>
</div>
{children}
</main>
);
}
103 changes: 48 additions & 55 deletions packages/console/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import logo from "@/assets/logo.png";

import { SplashScreen } from "@/components/spash-screen";

import { useNavigate, useParams } from "@solidjs/router";

import { Sheet } from "@/components/ui/sheet";
import { api } from "@/lib/api";
import { useNavigate, useParams } from "@solidjs/router";
import { createQuery, useQueryClient } from "@tanstack/solid-query";
import { createMemo } from "solid-js";
import {
Show,
Suspense,
createEffect,
createResource,
createSignal,
useTransition,
} from "solid-js";
Expand All @@ -21,12 +17,16 @@ import { EditBundleSheetContent } from "./_components/edit-bundle-sheet-content"
export default function Home() {
const params = useParams();
const navigate = useNavigate();
const queryClient = useQueryClient();

const bundleId = params.bundleId;

const [data, { refetch }] = createResource(() =>
api.getBundles.$get().then((res) => res.json()),
);
const data = createQuery(() => ({
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a good idea to extract it into hooks:
• useBundles() → returns all bundles
• useBundle(id) → returns a specific bundle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Console already has that getBundelById(id) in EditBundleSheetContent Component
I think getBundles is better in index.tsx

queryKey: ["getBundles"],
queryFn: () => {
return api.getBundles.$get().then((res) => res.json());
},
}));

const [selectedBundleId, setSelectedBundleId] = createSignal<string | null>(
bundleId,
Expand All @@ -42,52 +42,45 @@ export default function Home() {
navigate(`/${selectedBundleId()}`, { replace: true });
});

return (
<Suspense fallback={<SplashScreen />}>
<main class="w-full space-y-2.5">
<div class="flex flex-row items-center gap-1">
<img src={logo} alt="Hot Updater Console" class="w-12 h-12" />
<a
href="https://github.com/gronxb/hot-updater"
target="_blank"
class="text-2xl font-light"
rel="noreferrer"
>
Hot Updater Console
</a>
</div>
const dataForTable = createMemo(() => data.data || []);

<DataTable
columns={columns}
data={data}
onRowClick={(row) => {
start(() => {
setSelectedBundleId(row.id);
});
}}
/>
const handleClose = () => {
start(() => {
setSelectedBundleId(null);
queryClient.invalidateQueries({ queryKey: ["getBundles"] });
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn’t it okay if invalidate doesn’t happen when closing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleClose function is only activated with Clicking save button.
I think improving invalidation is safer.. but I don't think that has to be.
How about you? You don't think that as me?

});
};

return (
<>
<DataTable
columns={columns}
data={dataForTable}
onRowClick={(row) => {
start(() => {
setSelectedBundleId(row.id);
});
}}
/>

<Sheet
open={selectedBundleId() !== null}
onOpenChange={(open) =>
!open && start(() => setSelectedBundleId(null))
}
>
<Show when={selectedBundleId()}>
<Suspense>
<EditBundleSheetContent
bundleId={selectedBundleId()!}
onClose={() =>
start(() => {
setSelectedBundleId(null);
refetch();
})
}
/>
</Suspense>
</Show>
</Sheet>
</main>
</Suspense>
<Sheet
open={selectedBundleId() !== null}
onOpenChange={(open) =>
!open &&
start(() => {
setSelectedBundleId(null);
})
}
>
<Show when={selectedBundleId()}>
<Suspense>
<EditBundleSheetContent
bundleId={selectedBundleId()!}
onClose={handleClose}
/>
</Suspense>
</Show>
</Sheet>
</>
);
}
30 changes: 24 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.