diff --git a/renderer/atoms/translations-atom.ts b/renderer/atoms/translations-atom.ts index 8d7e9fc..67f45ba 100644 --- a/renderer/atoms/translations-atom.ts +++ b/renderer/atoms/translations-atom.ts @@ -11,11 +11,40 @@ import { atomWithStorage } from "jotai/utils"; type Translations = typeof en; type Locales = "en" | "ru" | "ja" | "zh" | "es" | "fr"; +const translations: Record = { + en, + ru, + ja, + zh, + es, + fr, +}; + +// Create a type for nested key paths +type NestedKeyOf = Object extends object + ? { + [Key in keyof Object]: Key extends string | number + ? Key | `${Key}.${NestedKeyOf}` + : never; + }[keyof Object] + : never; + // Utility function to access nested translation keys -const getNestedTranslation = (obj: Translations, key: string): string => { - return ( - key.split(".").reduce((acc, part) => acc && (acc as any)[part], obj) || key - ); +const getNestedTranslation = ( + obj: Translations, + key: NestedKeyOf, +): string => { + // Split the key into an array of nested parts + const keyParts = key.split("."); + + // Traverse the object using the key parts + const result = keyParts.reduce((currentObj, part) => { + // If currentObj is falsy or doesn't have the property, return undefined + return currentObj && currentObj[part]; + }, obj); + + // Return the found translation or the original key if not found + return result || key; }; // Atom to store the current locale @@ -24,16 +53,11 @@ export const localeAtom = atomWithStorage("language", "en"); // Atom to get the translation function based on the current locale export const translationAtom = atom((get) => { const locale = get(localeAtom); - const translations: Record = { - en, - ru, - ja, - zh, - es, - fr, - }; - return (key: string, params: Record = {}): string => { + return ( + key: NestedKeyOf, + params: Record = {}, + ): string => { const template = getNestedTranslation(translations[locale], key); // Replace placeholders with parameters, e.g., {name} => John diff --git a/renderer/components/Header.tsx b/renderer/components/Header.tsx index 3412a98..b90daa0 100644 --- a/renderer/components/Header.tsx +++ b/renderer/components/Header.tsx @@ -1,6 +1,6 @@ import { FEATURE_FLAGS } from "@common/feature-flags"; import React from "react"; -import Logo from "./icons/Logo"; +import UpscaylSVGLogo from "./icons/Logo"; import { useAtomValue } from "jotai"; import { translationAtom } from "@/atoms/translations-atom"; @@ -16,7 +16,7 @@ export default function Header({ version }: { version: string }) { data-tooltip-content={t("HEADER.GITHUB_BUTTON_TITLE")} >
- +

{t("TITLE")}{" "} diff --git a/renderer/components/NewsModal.tsx b/renderer/components/NewsModal.tsx index 12074ac..7c8b12f 100644 --- a/renderer/components/NewsModal.tsx +++ b/renderer/components/NewsModal.tsx @@ -1,27 +1,66 @@ +import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom"; import { translationAtom } from "@/atoms/translations-atom"; -import { GrayMatterFile } from "gray-matter"; -import { useAtomValue } from "jotai"; -import React from "react"; +import matter, { GrayMatterFile } from "gray-matter"; +import { useAtom, useAtomValue } from "jotai"; +import React, { useEffect } from "react"; import Markdown from "react-markdown"; import remarkGfm from "remark-gfm"; -export const NewsModal = ({ - show, - setShow, - news, -}: { - show: boolean; - setShow: React.Dispatch>; - news: GrayMatterFile; -}) => { +export const NewsModal = () => { const t = useAtomValue(translationAtom); + const [news, setNews] = useAtom(newsAtom); + const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom); + + useEffect(() => { + // TODO: ADD AN ABOUT TAB + if (window && window.navigator.onLine === false) return; + try { + fetch("https://raw.githubusercontent.com/upscayl/upscayl/main/news.md", { + cache: "no-cache", + }) + .then((res) => { + return res.text(); + }) + .then((result) => { + const newsData = result; + if (!newsData) { + console.log("📰 Could not fetch news data"); + return; + } + const markdownData = matter(newsData); + if (!markdownData) return; + if (markdownData && markdownData.data.dontShow) { + return; + } + if ( + markdownData && + news && + markdownData?.data?.version === news?.data?.version + ) { + console.log("📰 News is up to date"); + if (showNewsModal === false) { + setShowNewsModal(false); + } + } else if (markdownData) { + setNews(matter(newsData)); + setShowNewsModal(true); + } + }); + } catch (error) { + console.log("Could not fetch Upscayl News"); + } + }, [news]); + return ( - +
)} - + {!batchMode && viewType === "lens" && upscaledImagePath && imagePath && ( -
- {/* UPSCALED IMAGE */} - Upscaled - {/* LENS */} -
-
-
- Original -
-
- Upscaled -
-
-
- Original - Upscayl -
-
-
+ )} + {/* COMPARISON SLIDER */} {!batchMode && viewType === "slider" && imagePath.length > 0 && upscaledImagePath.length > 0 && ( - <> - -

- {t("APP.SLIDER.ORIGINAL_TITLE")} -

- - {t("APP.SLIDER.ORIGINAL_TITLE")} - - } - itemTwo={ - <> -

- {t("APP.SLIDER.UPSCAYLED_TITLE")} -

- {t("APP.SLIDER.UPSCAYLED_TITLE")} - - } - className="group h-screen" - /> - + )}

); diff --git a/renderer/components/main-content/lens-view.tsx b/renderer/components/main-content/lens-view.tsx new file mode 100644 index 0000000..002fb98 --- /dev/null +++ b/renderer/components/main-content/lens-view.tsx @@ -0,0 +1,92 @@ +import React, { useRef, useState } from "react"; + +const LensViewer = ({ + zoomAmount, + lensSize, + sanitizedImagePath, + sanitizedUpscaledImagePath, +}: { + zoomAmount: string; + lensSize: number; + sanitizedImagePath: string; + sanitizedUpscaledImagePath: string; +}) => { + const upscaledImageRef = useRef(null); + + const [lensPosition, setLensPosition] = useState({ x: 0, y: 0 }); + + const handleMouseMoveCompare = (e: React.MouseEvent) => { + if (upscaledImageRef.current) { + const { left, top, width, height } = + upscaledImageRef.current.getBoundingClientRect(); + const x = e.clientX - left; + const y = e.clientY - top; + setLensPosition({ + x: Math.max(0, Math.min(x - lensSize, width - lensSize * 2)), + y: Math.max(0, Math.min(y - lensSize / 2, height - lensSize)), + }); + } + }; + + return ( +
+ {/* UPSCALED IMAGE */} + Upscaled + {/* LENS */} +
+
+
+ Original +
+
+ Upscaled +
+
+
+ Original + Upscayl +
+
+
+ ); +}; + +export default LensViewer; diff --git a/renderer/components/main-content/mac-titlebar-drag-region.tsx b/renderer/components/main-content/mac-titlebar-drag-region.tsx new file mode 100644 index 0000000..97995aa --- /dev/null +++ b/renderer/components/main-content/mac-titlebar-drag-region.tsx @@ -0,0 +1,7 @@ +const MacTitlebarDragRegion = () => { + return window.electron.platform === "mac" ? ( +
+ ) : null; +}; + +export default MacTitlebarDragRegion; diff --git a/renderer/components/upscayl-tab/view/ProgressBar.tsx b/renderer/components/main-content/progress-bar.tsx similarity index 82% rename from renderer/components/upscayl-tab/view/ProgressBar.tsx rename to renderer/components/main-content/progress-bar.tsx index 4b500ca..95a3bad 100644 --- a/renderer/components/upscayl-tab/view/ProgressBar.tsx +++ b/renderer/components/main-content/progress-bar.tsx @@ -1,22 +1,24 @@ -import React, { CSSProperties, useEffect, useMemo } from "react"; -import Spinner from "../../icons/Spinner"; -import Logo from "@/components/icons/Logo"; +import React, { useEffect } from "react"; +import UpscaylSVGLogo from "@/components/icons/Logo"; import { useAtomValue } from "jotai"; import { translationAtom } from "@/atoms/translations-atom"; +import ELECTRON_COMMANDS from "@common/commands"; +import useLogger from "../hooks/use-logger"; function ProgressBar({ progress, doubleUpscaylCounter, - stopHandler, batchMode, + resetImagePaths, }: { progress: string; doubleUpscaylCounter: number; - stopHandler: () => void; batchMode: boolean; + resetImagePaths: () => void; }) { const [batchProgress, setBatchProgress] = React.useState(0); const t = useAtomValue(translationAtom); + const logit = useLogger(); useEffect(() => { const progressString = progress.trim().replace(/\n/g, ""); @@ -26,6 +28,12 @@ function ProgressBar({ } }, [progress]); + const stopHandler = () => { + window.electron.send(ELECTRON_COMMANDS.STOP); + logit("🛑 Stopping Upscayl"); + resetImagePaths(); + }; + // const progressStyle = useMemo(() => { // if (progress.includes("%")) { // return { @@ -44,11 +52,13 @@ function ProgressBar({ return (
- + +

{batchMode && `${t("APP.PROGRESS_BAR.BATCH_UPSCAYL_IN_PROGRESS_TITLE")} ${batchProgress}`}

+
{progress !== "Hold on..." ? (

@@ -60,10 +70,12 @@ function ProgressBar({ ) : (

{progress}

)} +

{t("APP.PROGRESS_BAR.IN_PROGRESS_TITLE")}

+ diff --git a/renderer/components/main-content/slider-view.tsx b/renderer/components/main-content/slider-view.tsx new file mode 100644 index 0000000..e387f1f --- /dev/null +++ b/renderer/components/main-content/slider-view.tsx @@ -0,0 +1,73 @@ +import React, { useCallback, useState } from "react"; +import { ReactCompareSlider } from "react-compare-slider"; +import useTranslation from "../hooks/use-translation"; + +const SliderView = ({ + sanitizedImagePath, + sanitizedUpscaledImagePath, + zoomAmount, +}: { + sanitizedImagePath: string; + sanitizedUpscaledImagePath: string; + zoomAmount: string; +}) => { + const t = useTranslation(); + + const [backgroundPosition, setBackgroundPosition] = useState("0% 0%"); + + const handleMouseMove = useCallback((e: any) => { + const { left, top, width, height } = e.target.getBoundingClientRect(); + const x = ((e.pageX - left) / width) * 100; + const y = ((e.pageY - top) / height) * 100; + setBackgroundPosition(`${x}% ${y}%`); + }, []); + + return ( + +

+ {t("APP.SLIDER.ORIGINAL_TITLE")} +

+ + {t("APP.SLIDER.ORIGINAL_TITLE")} + + } + itemTwo={ + <> +

+ {t("APP.SLIDER.UPSCAYLED_TITLE")} +

+ {t("APP.SLIDER.UPSCAYLED_TITLE")} + + } + className="group h-screen" + /> + ); +}; + +export default SliderView; diff --git a/renderer/components/settings-tab/DonateButton.tsx b/renderer/components/settings-tab/donate-button.tsx similarity index 100% rename from renderer/components/settings-tab/DonateButton.tsx rename to renderer/components/settings-tab/donate-button.tsx diff --git a/renderer/components/settings-tab/index.tsx b/renderer/components/settings-tab/index.tsx index d4a6dd5..3b21e24 100644 --- a/renderer/components/settings-tab/index.tsx +++ b/renderer/components/settings-tab/index.tsx @@ -1,26 +1,26 @@ -import { ThemeSelect } from "./ThemeSelect"; -import { SaveOutputFolderToggle } from "./SaveOutputFolderToggle"; -import { GpuIdInput } from "./GpuIdInput"; -import { CustomModelsFolderSelect } from "./CustomModelsFolderSelect"; -import { LogArea } from "./LogArea"; -import { ImageScaleSelect } from "./ImageScaleSelect"; -import { ImageFormatSelect } from "./ImageFormatSelect"; -import { DonateButton } from "./DonateButton"; +import { SelectTheme } from "./select-theme"; +import { SaveOutputFolderToggle } from "./save-output-folder-toggle"; +import { InputGpuId } from "./input-gpu-id"; +import { CustomModelsFolderSelect } from "./select-custom-models-folder"; +import { LogArea } from "./log-area"; +import { SelectImageScale } from "./select-image-scale"; +import { SelectImageFormat } from "./select-image-format"; +import { DonateButton } from "./donate-button"; import React, { useEffect, useState } from "react"; import { themeChange } from "theme-change"; import { useAtom, useAtomValue } from "jotai"; import { customModelsPathAtom, scaleAtom } from "../../atoms/userSettingsAtom"; import { modelsListAtom } from "../../atoms/modelsListAtom"; -import useLog from "../hooks/useLog"; -import { CompressionInput } from "./CompressionInput"; -import OverwriteToggle from "./OverwriteToggle"; +import useLogger from "../hooks/use-logger"; +import { InputCompression } from "./input-compression"; +import OverwriteToggle from "./overwrite-toggle"; import { UpscaylCloudModal } from "../UpscaylCloudModal"; -import { ResetSettings } from "./ResetSettings"; +import { ResetSettingsButton } from "./reset-settings-button"; import { FEATURE_FLAGS } from "@common/feature-flags"; -import TurnOffNotificationsToggle from "./TurnOffNotificationsToggle"; +import TurnOffNotificationsToggle from "./turn-off-notifications-toggle"; import { cn } from "@/lib/utils"; -import { CustomResolutionInput } from "./CustomResolutionInput"; -import { TileSizeInput } from "./TileSizeInput"; +import { InputCustomResolution } from "./input-custom-resolution"; +import { InputTileSize } from "./input-tile-size"; import LanguageSwitcher from "./language-switcher"; import { translationAtom } from "@/atoms/translations-atom"; @@ -34,7 +34,6 @@ interface IProps { gpuId: string; setGpuId: React.Dispatch>; logData: string[]; - os: "linux" | "mac" | "win" | undefined; show: boolean; setShow: React.Dispatch>; setDontShowCloudModal: React.Dispatch>; @@ -50,19 +49,11 @@ function SettingsTab({ saveImageAs, setSaveImageAs, logData, - os, + show, setShow, setDontShowCloudModal, }: IProps) { - // STATES - const [currentModel, setCurrentModel] = useState<{ - label: string; - value: string; - }>({ - label: null, - value: null, - }); const [isCopied, setIsCopied] = useState(false); const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom); @@ -72,7 +63,7 @@ function SettingsTab({ const [timeoutId, setTimeoutId] = useState(null); const t = useAtomValue(translationAtom); - const { logit } = useLog(); + const logit = useLogger(); useEffect(() => { themeChange(false); @@ -90,7 +81,6 @@ function SettingsTab({ } if (!localStorage.getItem("model")) { - setCurrentModel(modelOptions[0]); setModel(modelOptions[0].value); localStorage.setItem("model", JSON.stringify(modelOptions[0])); logit("🔀 Setting model to", modelOptions[0].value); @@ -107,7 +97,6 @@ function SettingsTab({ logit("🔀 Setting model to", modelOptions[0].value); currentlySavedModel = modelOptions[0]; } - setCurrentModel(currentlySavedModel); setModel(currentlySavedModel.value); logit( "⚙️ Getting model from localStorage: ", @@ -213,23 +202,23 @@ function SettingsTab({ /> {/* THEME SELECTOR */} - + {/* IMAGE FORMAT BUTTONS */} - {/* IMAGE SCALE */} - + - + - @@ -240,9 +229,9 @@ function SettingsTab({ {/* GPU ID INPUT */} - + - + {/* CUSTOM MODEL */} {/* RESET SETTINGS */} - + {FEATURE_FLAGS.SHOW_UPSCAYL_CLOUD_INFO && ( <> diff --git a/renderer/components/settings-tab/CompressionInput.tsx b/renderer/components/settings-tab/input-compression.tsx similarity index 96% rename from renderer/components/settings-tab/CompressionInput.tsx rename to renderer/components/settings-tab/input-compression.tsx index c021513..55af2ac 100644 --- a/renderer/components/settings-tab/CompressionInput.tsx +++ b/renderer/components/settings-tab/input-compression.tsx @@ -6,7 +6,7 @@ type CompressionInputProps = { handleCompressionChange: (arg: any) => void; }; -export function CompressionInput({ +export function InputCompression({ compression, handleCompressionChange, }: CompressionInputProps) { diff --git a/renderer/components/settings-tab/CustomResolutionInput.tsx b/renderer/components/settings-tab/input-custom-resolution.tsx similarity index 97% rename from renderer/components/settings-tab/CustomResolutionInput.tsx rename to renderer/components/settings-tab/input-custom-resolution.tsx index 0fa37e3..dc244c4 100644 --- a/renderer/components/settings-tab/CustomResolutionInput.tsx +++ b/renderer/components/settings-tab/input-custom-resolution.tsx @@ -3,7 +3,7 @@ import { useAtom, useAtomValue } from "jotai"; import React from "react"; import { translationAtom } from "@/atoms/translations-atom"; -export function CustomResolutionInput() { +export function InputCustomResolution() { const [useCustomWidth, setUseCustomWidth] = useAtom(useCustomWidthAtom); const [customWidth, setCustomWidth] = useAtom(customWidthAtom); const t = useAtomValue(translationAtom); diff --git a/renderer/components/settings-tab/GpuIdInput.tsx b/renderer/components/settings-tab/input-gpu-id.tsx similarity index 93% rename from renderer/components/settings-tab/GpuIdInput.tsx rename to renderer/components/settings-tab/input-gpu-id.tsx index 644b13d..a927248 100644 --- a/renderer/components/settings-tab/GpuIdInput.tsx +++ b/renderer/components/settings-tab/input-gpu-id.tsx @@ -7,7 +7,7 @@ type GpuIdInputProps = { handleGpuIdChange: (arg: string) => void; }; -export function GpuIdInput({ gpuId, handleGpuIdChange }) { +export function InputGpuId({ gpuId, handleGpuIdChange }) { const t = useAtomValue(translationAtom); return ( diff --git a/renderer/components/settings-tab/TileSizeInput.tsx b/renderer/components/settings-tab/input-tile-size.tsx similarity index 97% rename from renderer/components/settings-tab/TileSizeInput.tsx rename to renderer/components/settings-tab/input-tile-size.tsx index 6e62672..57f25d1 100644 --- a/renderer/components/settings-tab/TileSizeInput.tsx +++ b/renderer/components/settings-tab/input-tile-size.tsx @@ -3,7 +3,7 @@ import { tileSizeAtom } from "@/atoms/userSettingsAtom"; import { useAtom, useAtomValue } from "jotai"; import React from "react"; -export function TileSizeInput() { +export function InputTileSize() { const [tileSize, setTileSize] = useAtom(tileSizeAtom); const t = useAtomValue(translationAtom); diff --git a/renderer/components/settings-tab/LogArea.tsx b/renderer/components/settings-tab/log-area.tsx similarity index 100% rename from renderer/components/settings-tab/LogArea.tsx rename to renderer/components/settings-tab/log-area.tsx diff --git a/renderer/components/settings-tab/OverwriteToggle.tsx b/renderer/components/settings-tab/overwrite-toggle.tsx similarity index 100% rename from renderer/components/settings-tab/OverwriteToggle.tsx rename to renderer/components/settings-tab/overwrite-toggle.tsx diff --git a/renderer/components/settings-tab/ResetSettings.tsx b/renderer/components/settings-tab/reset-settings-button.tsx similarity index 93% rename from renderer/components/settings-tab/ResetSettings.tsx rename to renderer/components/settings-tab/reset-settings-button.tsx index d8016cd..66ffd6a 100644 --- a/renderer/components/settings-tab/ResetSettings.tsx +++ b/renderer/components/settings-tab/reset-settings-button.tsx @@ -2,7 +2,7 @@ import { translationAtom } from "@/atoms/translations-atom"; import { useAtomValue } from "jotai"; import React from "react"; -export function ResetSettings() { +export function ResetSettingsButton() { const t = useAtomValue(translationAtom); return (
diff --git a/renderer/components/settings-tab/SaveOutputFolderToggle.tsx b/renderer/components/settings-tab/save-output-folder-toggle.tsx similarity index 100% rename from renderer/components/settings-tab/SaveOutputFolderToggle.tsx rename to renderer/components/settings-tab/save-output-folder-toggle.tsx diff --git a/renderer/components/settings-tab/CustomModelsFolderSelect.tsx b/renderer/components/settings-tab/select-custom-models-folder.tsx similarity index 100% rename from renderer/components/settings-tab/CustomModelsFolderSelect.tsx rename to renderer/components/settings-tab/select-custom-models-folder.tsx diff --git a/renderer/components/settings-tab/ImageFormatSelect.tsx b/renderer/components/settings-tab/select-image-format.tsx similarity index 97% rename from renderer/components/settings-tab/ImageFormatSelect.tsx rename to renderer/components/settings-tab/select-image-format.tsx index 233e64e..134043f 100644 --- a/renderer/components/settings-tab/ImageFormatSelect.tsx +++ b/renderer/components/settings-tab/select-image-format.tsx @@ -7,7 +7,7 @@ type ImageFormatSelectProps = { setExportType: (arg: string) => void; }; -export function ImageFormatSelect({ +export function SelectImageFormat({ batchMode, saveImageAs, setExportType, diff --git a/renderer/components/settings-tab/ImageScaleSelect.tsx b/renderer/components/settings-tab/select-image-scale.tsx similarity index 98% rename from renderer/components/settings-tab/ImageScaleSelect.tsx rename to renderer/components/settings-tab/select-image-scale.tsx index 6430902..83ad017 100644 --- a/renderer/components/settings-tab/ImageScaleSelect.tsx +++ b/renderer/components/settings-tab/select-image-scale.tsx @@ -8,7 +8,7 @@ type ImageScaleSelectProps = { hideInfo?: boolean; }; -export function ImageScaleSelect({ +export function SelectImageScale({ scale, setScale, hideInfo, diff --git a/renderer/components/settings-tab/ThemeSelect.tsx b/renderer/components/settings-tab/select-theme.tsx similarity index 98% rename from renderer/components/settings-tab/ThemeSelect.tsx rename to renderer/components/settings-tab/select-theme.tsx index 087383d..033b36c 100644 --- a/renderer/components/settings-tab/ThemeSelect.tsx +++ b/renderer/components/settings-tab/select-theme.tsx @@ -1,7 +1,8 @@ import { translationAtom } from "@/atoms/translations-atom"; import { useAtomValue } from "jotai"; import React from "react"; -export function ThemeSelect() { + +export function SelectTheme() { const availableThemes = [ { label: "upscayl", value: "upscayl" }, { label: "light", value: "light" }, diff --git a/renderer/components/settings-tab/TurnOffNotificationsToggle.tsx b/renderer/components/settings-tab/turn-off-notifications-toggle.tsx similarity index 100% rename from renderer/components/settings-tab/TurnOffNotificationsToggle.tsx rename to renderer/components/settings-tab/turn-off-notifications-toggle.tsx diff --git a/renderer/components/sidebar/index.tsx b/renderer/components/sidebar/index.tsx index 534e7e6..01b8107 100644 --- a/renderer/components/sidebar/index.tsx +++ b/renderer/components/sidebar/index.tsx @@ -15,27 +15,26 @@ import { tileSizeAtom, showSidebarAtom, } from "../../atoms/userSettingsAtom"; -import useLog from "../../components/hooks/useLog"; +import useLogger from "../hooks/use-logger"; import { BatchUpscaylPayload, DoubleUpscaylPayload, ImageUpscaylPayload, } from "@common/types/types"; -import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom"; import { useToast } from "@/components/ui/use-toast"; -import Logo from "@/components/icons/Logo"; -import { translationAtom } from "@/atoms/translations-atom"; import LeftPaneImageSteps from "../upscayl-tab/config/LeftPaneImageSteps"; import SettingsTab from "../settings-tab"; import Footer from "../Footer"; import { NewsModal } from "../NewsModal"; import Tabs from "../Tabs"; import Header from "../Header"; -import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; -import { cn } from "@/lib/utils"; +import { ChevronLeftIcon } from "lucide-react"; import { logAtom } from "@/atoms/logAtom"; import ELECTRON_COMMANDS from "@common/commands"; import useUpscaylVersion from "../hooks/use-upscayl-version"; +import useTranslation from "../hooks/use-translation"; +import UpscaylLogo from "./upscayl-logo"; +import SidebarToggleButton from "./sidebar-button"; const Sidebar = ({ setUpscaledImagePath, @@ -57,14 +56,13 @@ const Sidebar = ({ selectImageHandler: () => Promise; selectFolderHandler: () => Promise; }) => { - const t = useAtomValue(translationAtom); - const { logit } = useLog(); + const t = useTranslation(); + const logit = useLogger(); const { toast } = useToast(); const version = useUpscaylVersion(); // LOCAL STATES // TODO: Add electron handler for os - const [os, setOs] = useState<"linux" | "mac" | "win" | undefined>(undefined); const [model, setModel] = useState("realesrgan-x4plus"); const [doubleUpscayl, setDoubleUpscayl] = useState(false); const overwrite = useAtomValue(overwriteAtom); @@ -83,8 +81,6 @@ const Sidebar = ({ const [scale] = useAtom(scaleAtom); const setDontShowCloudModal = useSetAtom(dontShowCloudModalAtom); const noImageProcessing = useAtomValue(noImageProcessingAtom); - const [news, setNews] = useAtom(newsAtom); - const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom); const customWidth = useAtomValue(customWidthAtom); const useCustomWidth = useAtomValue(useCustomWidthAtom); const tileSize = useAtomValue(tileSizeAtom); @@ -174,25 +170,13 @@ const Sidebar = ({ return ( <> {/* TOP LOGO WHEN SIDEBAR IS HIDDEN */} - {!showSidebar && ( -
- - {t("TITLE")} -
- )} + {!showSidebar && } - {/* SIDEBAR BUTTON */} - + - {/* LEFT PANE */}
@@ -203,22 +187,13 @@ const Sidebar = ({ - {/* MACOS TITLEBAR */} {window.electron.platform === "mac" && (
)} - {/* HEADER */} +
- {/* NEWS DIALOG */} - { - setShowNewsModal(val); - setNews((prev) => ({ ...prev, seen: true })); - }} - news={news} - /> + @@ -252,13 +227,11 @@ const Sidebar = ({ saveImageAs={saveImageAs} setSaveImageAs={setSaveImageAs} logData={logData} - os={os} show={showCloudModal} setShow={setShowCloudModal} setDontShowCloudModal={setDontShowCloudModal} /> )} - {/* )} */}
diff --git a/renderer/components/sidebar/sidebar-button.tsx b/renderer/components/sidebar/sidebar-button.tsx new file mode 100644 index 0000000..db532f5 --- /dev/null +++ b/renderer/components/sidebar/sidebar-button.tsx @@ -0,0 +1,25 @@ +import { cn } from "@/lib/utils"; +import { ChevronRightIcon } from "lucide-react"; +import React from "react"; + +const SidebarToggleButton = ({ + showSidebar, + setShowSidebar, +}: { + showSidebar: boolean; + setShowSidebar: React.Dispatch>; +}) => { + return ( + + ); +}; + +export default SidebarToggleButton; diff --git a/renderer/components/sidebar/upscayl-logo.tsx b/renderer/components/sidebar/upscayl-logo.tsx new file mode 100644 index 0000000..5c242b2 --- /dev/null +++ b/renderer/components/sidebar/upscayl-logo.tsx @@ -0,0 +1,15 @@ +import UpscaylSVGLogo from "../icons/Logo"; +import useTranslation from "../hooks/use-translation"; + +const UpscaylLogo = () => { + const t = useTranslation(); + + return ( +
+ + {t("TITLE")} +
+ ); +}; + +export default UpscaylLogo; diff --git a/renderer/components/upscayl-tab/config/LeftPaneImageSteps.tsx b/renderer/components/upscayl-tab/config/LeftPaneImageSteps.tsx index 6543311..c3d4d6a 100644 --- a/renderer/components/upscayl-tab/config/LeftPaneImageSteps.tsx +++ b/renderer/components/upscayl-tab/config/LeftPaneImageSteps.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { Tooltip } from "react-tooltip"; import { themeChange } from "theme-change"; import { TModelsList, modelsListAtom } from "../../../atoms/modelsListAtom"; -import useLog from "../../hooks/useLog"; +import useLogger from "../../hooks/use-logger"; import { noImageProcessingAtom, savedOutputPathAtom, @@ -76,7 +76,7 @@ function LeftPaneImageSteps({ const [targetWidth, setTargetWidth] = useState(null); const [targetHeight, setTargetHeight] = useState(null); - const { logit } = useLog(); + const logit = useLogger(); const { toast } = useToast(); const t = useAtomValue(translationAtom); diff --git a/renderer/components/upscayl-tab/view/ImageOptions.tsx b/renderer/components/upscayl-tab/view/ImageOptions.tsx index 9e7f51c..22a3bd9 100644 --- a/renderer/components/upscayl-tab/view/ImageOptions.tsx +++ b/renderer/components/upscayl-tab/view/ImageOptions.tsx @@ -5,7 +5,7 @@ import { useAtom, useAtomValue } from "jotai"; import { WrenchIcon } from "lucide-react"; import { useEffect, useState } from "react"; -const ImageOptions = ({ +const ImageViewSettings = ({ zoomAmount, setZoomAmount, resetImagePaths, @@ -113,4 +113,4 @@ const ImageOptions = ({ ); }; -export default ImageOptions; +export default ImageViewSettings; diff --git a/renderer/components/upscayl-tab/view/RightPaneInfo.tsx b/renderer/components/upscayl-tab/view/RightPaneInfo.tsx index 18511c4..d40189d 100644 --- a/renderer/components/upscayl-tab/view/RightPaneInfo.tsx +++ b/renderer/components/upscayl-tab/view/RightPaneInfo.tsx @@ -2,7 +2,7 @@ import { translationAtom } from "@/atoms/translations-atom"; import { useAtomValue } from "jotai"; import React from "react"; -function RightPaneInfo({ version, batchMode }) { +function InformationCard({ version, batchMode }) { const t = useAtomValue(translationAtom); return ( @@ -26,4 +26,4 @@ function RightPaneInfo({ version, batchMode }) { ); } -export default RightPaneInfo; +export default InformationCard; diff --git a/renderer/pages/index.tsx b/renderer/pages/index.tsx index a151230..187d524 100644 --- a/renderer/pages/index.tsx +++ b/renderer/pages/index.tsx @@ -9,12 +9,12 @@ import { progressAtom, rememberOutputFolderAtom, } from "../atoms/userSettingsAtom"; -import useLog from "../components/hooks/useLog"; +import useLogger from "../components/hooks/use-logger"; import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom"; import matter from "gray-matter"; import { useToast } from "@/components/ui/use-toast"; import { ToastAction } from "@/components/ui/toast"; -import Logo from "@/components/icons/Logo"; +import UpscaylSVGLogo from "@/components/icons/Logo"; import { translationAtom } from "@/atoms/translations-atom"; import Sidebar from "@/components/sidebar"; import MainContent from "@/components/main-content"; @@ -25,7 +25,7 @@ import { initCustomModels } from "@/components/hooks/use-custom-models"; const Home = () => { const t = useAtomValue(translationAtom); - const { logit } = useLog(); + const logit = useLogger(); const { toast } = useToast(); initCustomModels(); @@ -279,47 +279,6 @@ const Home = () => { ); }, []); - // FETCH NEWS - useEffect(() => { - // TODO: ADD AN ABOUT TAB - if (window && window.navigator.onLine === false) return; - try { - fetch("https://raw.githubusercontent.com/upscayl/upscayl/main/news.md", { - cache: "no-cache", - }) - .then((res) => { - return res.text(); - }) - .then((result) => { - const newsData = result; - if (!newsData) { - console.log("📰 Could not fetch news data"); - return; - } - const markdownData = matter(newsData); - if (!markdownData) return; - if (markdownData && markdownData.data.dontShow) { - return; - } - if ( - markdownData && - news && - markdownData?.data?.version === news?.data?.version - ) { - console.log("📰 News is up to date"); - if (showNewsModal === false) { - setShowNewsModal(false); - } - } else if (markdownData) { - setNews(matter(newsData)); - setShowNewsModal(true); - } - }); - } catch (error) { - console.log("Could not fetch Upscayl News"); - } - }, [news]); - // LOADING STATE useEffect(() => { setIsLoading(false); @@ -341,7 +300,7 @@ const Home = () => { if (isLoading) { return ( - + ); }