Skip to content

Commit

Permalink
Two-Column Organizing Alphabetized
Browse files Browse the repository at this point in the history
- The two-column theme view now alphabetically sorts themes left-to-right, top-to-bottom.

- Additionally, large refactors of clunky components and functions across the board.
  • Loading branch information
beebls committed Jun 13, 2023
1 parent e5cb835 commit 424718c
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 137 deletions.
63 changes: 63 additions & 0 deletions components/ManageThemes/ManageThemeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BsFillCloudDownloadFill, BsTrashFill } from "react-icons/bs";
import { MinimalCSSThemeInfo, Theme } from "../../ThemeTypes";
import { LocalThemeStatus } from "../../pages/manage-themes";
import { UpdateStatus } from "../../logic";

export function ManageThemeCard({
themeData,
updateStatuses,
uninstalling,
handleUninstall,
handleUpdate,
}: {
themeData: Theme;
updateStatuses: UpdateStatus[];
uninstalling: boolean;
handleUninstall: any;
handleUpdate: any;
}) {
// This finds the remote entry for the current theme (if it exists), and sets the data accordingly
let [updateStatus, remoteEntry]: [
LocalThemeStatus,
false | MinimalCSSThemeInfo
] = ["installed", false];
const themeArrPlace = updateStatuses.find((f) => f[0] === themeData.id);
if (themeArrPlace) {
updateStatus = themeArrPlace[1];
remoteEntry = themeArrPlace[2];
}
return (
<div className="flex bg-cardDark p-4 rounded-xl items-center justify-center w-[320px] 2cols:w-[640px]">
<div className="flex flex-col">
<span>{themeData.name}</span>
<span>
{themeData.version}
{updateStatus === "local" ? (
<span className="italic text-slate-200"> - Local Theme</span>
) : (
""
)}
</span>
</div>
<div className="flex ml-auto items-center justify-center gap-2 2cols:gap-4">
{updateStatus === "outdated" && remoteEntry && (
<button
onClick={() => remoteEntry && handleUpdate(remoteEntry)}
className="flex flex-col 2cols:flex-row-reverse 2cols:gap-2 items-center justify-center"
>
<BsFillCloudDownloadFill className="text-2xl 2cols:text-3xl" />
<span>{remoteEntry.version}</span>
</button>
)}
<div className="flex items-center justify-center">
<button
disabled={uninstalling}
onClick={() => handleUninstall(themeData)}
>
<BsTrashFill className="text-2xl 2cols:text-3xl" />
</button>
</div>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions components/ManageThemes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ManageThemeCard";
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions components/YourThemes/OneColumnThemeView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useContext } from "react";
import { themeContext } from "../../pages/_app";
import { ThemeToggle } from "../SingleTheme";

export function OneColumnThemeView() {
const { themes } = useContext(themeContext);

return (
<div className="flex flex-wrap items-start w-[320px] 2cols:w-[650px] 3cols:w-[980px] 4cols:w-[1310px] 5cols:w-[1680px] gap-[10px]">
{themes.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
);
}
44 changes: 44 additions & 0 deletions components/YourThemes/TwoColumnThemeView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useContext, useMemo } from "react";
import { themeContext } from "../../pages/_app";
import { ThemeToggle } from "../SingleTheme";
import { Theme } from "../../ThemeTypes";

export function TwoColumnThemeView() {
const { themes } = useContext(themeContext);

// This takes the list of themes and returns two columns
// When these columns are displayed as left and right, the themes inside will read alphabetically, left ro right and top to bottom.
// A B
// C D
// E F
// etc, etc
const [leftColumn, rightColumn] = useMemo(() => {
let leftColumn: Theme[] = [],
rightColumn: Theme[] = [];
themes.sort().forEach((e, i) => {
if (i % 2 === 0) {
leftColumn.push(e);
} else {
rightColumn.push(e);
}
});
return [leftColumn, rightColumn];
}, [themes]);

// If you're wondering "why not CSS grid", it's because each theme has it's own unique height
// Having the left-col theme affect the right-col theme's height looked bad
return (
<div className="flex gap-[10px]">
<div className="flex flex-col items-start w-[320px] gap-[4px]">
{leftColumn.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
<div className="flex flex-col items-start w-[320px] gap-[4px]">
{rightColumn.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
</div>
);
}
2 changes: 2 additions & 0 deletions components/YourThemes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./TwoColumnThemeView";
export * from "./OneColumnThemeView";
4 changes: 3 additions & 1 deletion components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from "./Theme";
export * from "./SingleTheme";
export * from "./Nav";
export * from "./DownloadBackendPage";
export * from "./BackendFailedPage";
export * from "./CreatePresetModal";
export * from "./YourThemes";
export * from "./ManageThemes";
3 changes: 2 additions & 1 deletion hooks/usePlatform.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Platform } from "@tauri-apps/api/os";
import { useEffect, useState } from "react";

// Unused ATM
// This was originally intended to be used to gate backend-installation to windows, as lord knows I can't write a systemd service to do it on linux
export function usePlatform() {
const [platform, setPlatform] = useState<Platform>("linux");

useEffect(() => {
const getPlatform = async () => {
const { platform: tauriPlatform } = await import("@tauri-apps/api/os");
Expand Down
48 changes: 48 additions & 0 deletions logic/bulkThemeUpdateCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { MinimalCSSThemeInfo, Theme } from "../ThemeTypes";
import { LocalThemeStatus } from "../pages/manage-themes";
import { apiUrl } from "../constants";
import { fetch } from "@tauri-apps/api/http";

export type UpdateStatus = [
string,
LocalThemeStatus,
false | MinimalCSSThemeInfo
];

async function fetchThemeIDS(
idsToQuery: string[]
): Promise<MinimalCSSThemeInfo[]> {
const queryStr = "?ids=" + idsToQuery.join(".");
return fetch<MinimalCSSThemeInfo[]>(`${apiUrl}/themes/ids${queryStr}`)
.then((res) => {
return res.data;
})
.then((data) => {
if (data) return data;
return [];
})
.catch((err) => {
console.error("Error Fetching Theme Updates!", err);
return [];
});
}

export async function bulkThemeUpdateCheck(localThemeList: Theme[] = []) {
let idsToQuery: string[] = localThemeList.map((e) => e.id);
if (idsToQuery.length === 0) return [];

const themeArr = await fetchThemeIDS(idsToQuery);
if (themeArr.length === 0) return [];

const updateStatusArr: UpdateStatus[] = localThemeList.map((localEntry) => {
const remoteEntry = themeArr.find(
(remote) => remote.id === localEntry.id || remote.name === localEntry.id
);
if (!remoteEntry) return [localEntry.id, "local", false];
if (remoteEntry.version === localEntry.version)
return [localEntry.id, "installed", remoteEntry];
return [localEntry.id, "outdated", remoteEntry];
});

return updateStatusArr;
}
1 change: 1 addition & 0 deletions logic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./bulkThemeUpdateCheck";
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "CSSLoader-Desktop",
"version": "0.6.1",
"version": "0.6.2",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
35 changes: 6 additions & 29 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,18 @@
import { useContext } from "react";
import { ThemeToggle } from "../components";
import { themeContext } from "./_app";
import {
OneColumnThemeView,
TwoColumnThemeView,
CreatePresetModal,
} from "../components";
import { useVW } from "../hooks/useVW";
import { CreatePresetModal } from "../components";

export default function MainPage() {
const { themes: localThemeList } = useContext(themeContext);
const vw = useVW();

return (
<>
<div className="flex items-center flex-col pb-10">
<div className="flex justify-center">
{vw <= 650 ? (
<div className="flex flex-wrap items-start w-[320px] 2cols:w-[650px] 3cols:w-[980px] 4cols:w-[1310px] 5cols:w-[1680px] gap-[10px]">
{localThemeList.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
) : (
<div className="flex gap-[10px]">
<div className="flex flex-col items-start w-[320px] gap-[4px]">
{localThemeList
.slice(0, Math.round(localThemeList.length / 2))
.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
<div className="flex flex-col items-start w-[320px] gap-[4px]">
{localThemeList
.slice(Math.round(localThemeList.length / 2))
.map((e) => {
return <ThemeToggle data={e} key={`Theme_${e.name}`} />;
})}
</div>
</div>
)}
{vw <= 650 ? <OneColumnThemeView /> : <TwoColumnThemeView />}
</div>
<CreatePresetModal />
</div>
Expand Down
Loading

0 comments on commit 424718c

Please sign in to comment.