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

v3.0.0 Release #6

Merged
merged 2 commits into from
Jan 22, 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
16 changes: 8 additions & 8 deletions app/components/ConvertButton/ConvertButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useAtom } from "jotai";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
filePathsAtom,
fileInfosAtom,
Expand All @@ -16,15 +16,15 @@ import "@ant-design/v5-patch-for-react-19";
import { useState } from "react";

export default function ConvertButton() {
const [filePaths] = useAtom(filePathsAtom);
const [fileInfos] = useAtom(fileInfosAtom);
const [extensionType] = useAtom(extensionTypeAtom);
const [quality] = useAtom(qualityAtom);
const filePaths = useAtomValue(filePathsAtom);
const fileInfos = useAtomValue(fileInfosAtom);
const extensionType = useAtomValue(extensionTypeAtom);
const quality = useAtomValue(qualityAtom);
const [isProcessing, setIsProcessing] = useAtom(isProcessingAtom);
const [, setProcessedFilePaths] = useAtom(processedFilePathsAtom);
const [, setTabSelected] = useAtom(tabSelectedAtom);
const setProcessedFilePaths = useSetAtom(processedFilePathsAtom);
const setTabSelected = useSetAtom(tabSelectedAtom);
const [dialog, setDialog] = useState<React.ReactNode | null>(null);
const [, setOutputTempDir] = useAtom(outputTempDirAtom);
const setOutputTempDir = useSetAtom(outputTempDirAtom);

const handleConvert = async () => {
const errorDialog = await convert(
Expand Down
6 changes: 3 additions & 3 deletions app/components/Dropzone/Dropzone.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"use client";
import { useEffect, useState } from "react";
import { useAtom } from "jotai";
import { useSetAtom } from "jotai";
import { filePathsAtom, tabSelectedAtom } from "../../lib/atom";
import { WarningDialog, ErrorDialog } from "../Dialog/Dialog";
import { listen } from "@tauri-apps/api/event";

export default function Dropzone() {
const [, setFilePaths] = useAtom(filePathsAtom);
const [, setTabSelected] = useAtom(tabSelectedAtom);
const setFilePaths = useSetAtom(filePathsAtom);
const setTabSelected = useSetAtom(tabSelectedAtom);
const [warningModalOpen, setWarningModalOpen] = useState(false);
const [errorModalOpen, setErrorModalOpen] = useState(false);
const [extensions, setExtensions] = useState<string[]>([]);
Expand Down
6 changes: 3 additions & 3 deletions app/components/InputTab/InputNavMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import "@ant-design/v5-patch-for-react-19";
import FileDialog from "../FileDialog/FileDialog";
import { Button } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
import { useAtom } from "jotai";
import { useSetAtom } from "jotai";
import { filePathsAtom, fileInfosAtom } from "../../lib/atom";

export default function InputNubMenu() {
const [, setFilePaths] = useAtom(filePathsAtom);
const [, setFileInfos] = useAtom(fileInfosAtom);
const setFilePaths = useSetAtom(filePathsAtom);
const setFileInfos = useSetAtom(fileInfosAtom);

const removeAll = () => {
setFilePaths([]);
Expand Down
6 changes: 3 additions & 3 deletions app/components/InputTab/InputTab.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"use client";

import SelectFiles from "../SelectFiles/SelectFiles";
import { useAtom } from "jotai";
import { useAtomValue } from "jotai";
import { tabSelectedAtom, filePathsAtom } from "../../lib/atom";
import InputNubMenu from "./InputNavMenu";
import Null from "./Null";
import Dropzone from "../Dropzone/Dropzone";

export default function InputTab() {
const [tabSelected] = useAtom(tabSelectedAtom);
const [filePaths] = useAtom(filePathsAtom);
const tabSelected = useAtomValue(tabSelectedAtom);
const filePaths = useAtomValue(filePathsAtom);

return (
<div
Expand Down
8 changes: 4 additions & 4 deletions app/components/LoadingModal/LoadingModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import { useAtom } from "jotai";
import { useAtomValue } from "jotai";
import {
isProcessingAtom,
isSavingAtom,
Expand All @@ -9,9 +9,9 @@ import { Spin } from "antd";
import "@ant-design/v5-patch-for-react-19";

export default function LoadingModal() {
const [isProcessing] = useAtom(isProcessingAtom);
const [isSaving] = useAtom(isSavingAtom);
const [extensionType] = useAtom(extensionTypeAtom);
const isProcessing = useAtomValue(isProcessingAtom);
const isSaving = useAtomValue(isSavingAtom);
const extensionType = useAtomValue(extensionTypeAtom);
return (
<div
className={`fixed h-[calc(100vh-30px)] bottom-0 left-0 right-0 top-[30px] bg-black/50 flex justify-center items-center z-50 ${
Expand Down
8 changes: 4 additions & 4 deletions app/components/OutputTab/OutputNavMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button } from "antd";
import { useAtom } from "jotai";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
processedFilePathsSortedAtom,
checkboxSelectedAtom,
Expand All @@ -21,10 +21,10 @@ export default function OutputNavMenu() {
processedFilePathsSortedAtom
);
const [checkboxSelected, setCheckboxSelected] = useAtom(checkboxSelectedAtom);
const [, setProcessedFilePaths] = useAtom(processedFilePathsAtom);
const [, setIsSaving] = useAtom(isSavingAtom);
const setProcessedFilePaths = useSetAtom(processedFilePathsAtom);
const setIsSaving = useSetAtom(isSavingAtom);
const [dialog, setDialog] = useState<React.ReactNode | null>(null);
const [outputTempDir,] = useAtom(outputTempDirAtom);
const outputTempDir = useAtomValue(outputTempDirAtom);

const handleSaveAll = async () => {
const result = await saveAll(setIsSaving, processedFilePathsSorted, setDialog);
Expand Down
4 changes: 2 additions & 2 deletions app/components/OutputTab/OutputTab.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";

import { useAtom } from "jotai";
import { useAtomValue } from "jotai";
import { tabSelectedAtom } from "../../lib/atom";
import ProcessedFiles from "../ProcessedFiles/ProcessedFiles";
import OutputNavMenu from "./OutputNavMenu";

export default function OutputTab() {
const [tabSelected] = useAtom(tabSelectedAtom);
const tabSelected = useAtomValue(tabSelectedAtom);
return (
<div
className={`flex flex-col w-full h-full relative pb-2 bg-white/80 ${
Expand Down
28 changes: 5 additions & 23 deletions app/components/ProcessedFiles/File.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"use client";
import { ProcessedFilesProps } from ".";
import RightArrow from "../icons/RightArrow";
import { useAtom } from "jotai";
import { useAtom, useAtomValue } from "jotai";
import { checkboxSelectedAtom, filePathsAtom } from "@/app/lib/atom";
import { ProcessedFileInfo } from "@/app/index.d";
import { useEffect, useState } from "react";
import { readFile } from "@tauri-apps/plugin-fs";
import "@ant-design/v5-patch-for-react-19";
import CheckOutlined from "../icons/Check";
import { convertFileSrc } from "@tauri-apps/api/core";

function getCompressionRate(processedFileInfo: ProcessedFileInfo) {
const compressionRate: number = parseFloat(
Expand All @@ -26,24 +25,7 @@ export default function File({
processedFileInfo,
}: ProcessedFilesProps) {
const [checkboxSelected, setCheckboxSelected] = useAtom(checkboxSelectedAtom);
const [filePaths] = useAtom(filePathsAtom);

const [imageSrc, setImageSrc] = useState<string | null>(null);

useEffect(() => {
const handleImageLoad = async (filePath: string) => {
try {
const data = await readFile(filePath);
const blob = new Blob([data], { type: "image/jpeg" });
const url = URL.createObjectURL(blob);
setImageSrc(url);
} catch (error) {
console.error("ファイルの読み込みに失敗しました:", error);
}
};

handleImageLoad(filePaths[index]);
}, [processedFileInfo.file_name_with_extension]);
const filePaths = useAtomValue(filePathsAtom);

const compressionRate = getCompressionRate(processedFileInfo);

Expand All @@ -57,9 +39,9 @@ export default function File({
{index + 1}
</span>
<div className="flex items-center aspect-square w-20 h-auto min-w-[90px]">
{imageSrc && (
{filePaths[index] && (
<img
src={imageSrc}
src={convertFileSrc(filePaths[index])}
alt={processedFileInfo.file_name_with_extension}
loading="lazy"
/>
Expand Down
8 changes: 4 additions & 4 deletions app/components/ProcessedFiles/ProcessedFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useAtom } from "jotai";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
fileInfosAtom,
processedFilePathsAtom,
Expand All @@ -14,15 +14,15 @@ import { getProcessedFileInfo } from "../SelectFiles/utils";
import type { ProcessedFileInfo } from "@/app/index.d";

export default function ProcessedFiles() {
const [fileInfos] = useAtom(fileInfosAtom);
const [processedFilePaths] = useAtom(processedFilePathsAtom);
const fileInfos = useAtomValue(fileInfosAtom);
const processedFilePaths = useAtomValue(processedFilePathsAtom);
const [processedFileInfos, setProcessedFileInfos] = useAtom(
processedFileInfosAtom
);
const [processedFilePathsSorted, setProcessedFilePathsSorted] = useAtom(
processedFilePathsSortedAtom
);
const [, setCheckboxSelected] = useAtom(checkboxSelectedAtom);
const setCheckboxSelected = useSetAtom(checkboxSelectedAtom);

useEffect(() => {
const fetchProcessedInfos = async () => {
Expand Down
27 changes: 5 additions & 22 deletions app/components/SelectFiles/File.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,14 @@
import { FileProps } from "./index.d";
import { Button } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
import { useAtom } from "jotai";
import { useAtom, useSetAtom } from "jotai";
import { filePathsAtom, fileInfosAtom } from "../../lib/atom";
import { useState, useEffect } from "react";
import { readFile } from "@tauri-apps/plugin-fs";
import { convertFileSrc } from "@tauri-apps/api/core";
import "@ant-design/v5-patch-for-react-19";

export default function File({ fileInfo, index }: FileProps) {
const [filePaths, setFilePaths] = useAtom(filePathsAtom);
const [, setFileInfos] = useAtom(fileInfosAtom);
const [imageSrc, setImageSrc] = useState<string | null>(null);

useEffect(() => {
const handleImageLoad = async (filePath: string) => {
try {
const data = await readFile(filePath);
const blob = new Blob([data], { type: "image/jpeg" });
const url = URL.createObjectURL(blob);
setImageSrc(url);
} catch (error) {
console.error("ファイルの読み込みに失敗しました:", error);
}
};

handleImageLoad(filePaths[index]);
}, [fileInfo.file_name_with_extension]);
const setFileInfos = useSetAtom(fileInfosAtom);

const extension =
fileInfo.file_name_with_extension.split(".").pop()?.toLowerCase() || "";
Expand All @@ -46,9 +29,9 @@ export default function File({ fileInfo, index }: FileProps) {
{index + 1}
</span>
<div className="flex items-center aspect-square w-20 h-auto min-w-[90px]">
{imageSrc && (
{filePaths[index] && (
<img
src={imageSrc}
src={convertFileSrc(filePaths[index])}
alt={fileInfo.file_name_with_extension}
loading="lazy"
/>
Expand Down
4 changes: 2 additions & 2 deletions app/components/SelectFiles/SelectFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useAtom } from "jotai";
import { useAtom, useAtomValue } from "jotai";
import { filePathsAtom, fileInfosAtom } from "@/app/lib/atom";
import { FileInfo } from "@/app/index.d";
import { useEffect } from "react";
Expand All @@ -9,7 +9,7 @@ import { getFileInfo } from "./utils";
import { readFileAsync } from "../FileDialog/utils";

export default function SelectFiles() {
const [filePaths] = useAtom(filePathsAtom);
const filePaths = useAtomValue(filePathsAtom);
const [fileInfos, setFileInfos] = useAtom(fileInfosAtom);

useEffect(() => {
Expand Down
48 changes: 24 additions & 24 deletions app/components/WindowMenu/ContextMenu/FileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type { MenuProps } from "antd";
import { Dropdown } from "antd";
import { useAtom } from "jotai";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
fileInfosAtom,
filePathsAtom,
Expand Down Expand Up @@ -53,21 +53,21 @@ const items: MenuProps["items"] = [

export default function FileMenu() {
const [filePaths, setFilePaths] = useAtom(filePathsAtom);
const [isFocused] = useAtom(isFocusedAtom);
const isFocused = useAtomValue(isFocusedAtom);
const fileButtonRef = useRef<HTMLButtonElement | null>(null);
const [fileInfos, setFileInfos] = useAtom(fileInfosAtom);
const [tabSelected, setTabSelected] = useAtom(tabSelectedAtom);
const [processedFilePathsSorted, setProcessedFilePathsSorted] = useAtom(
processedFilePathsSortedAtom
);
const [checkboxSelected, setCheckboxSelected] = useAtom(checkboxSelectedAtom);
const [, setProcessedFilePaths] = useAtom(processedFilePathsAtom);
const setProcessedFilePaths = useSetAtom(processedFilePathsAtom);
const [isSaving, setIsSaving] = useAtom(isSavingAtom);
const [quality] = useAtom(qualityAtom);
const [extensionType] = useAtom(extensionTypeAtom);
const quality = useAtomValue(qualityAtom);
const extensionType = useAtomValue(extensionTypeAtom);
const [isProcessing, setIsProcessing] = useAtom(isProcessingAtom);
const [, setDialog] = useAtom(windowMenuDialogAtom);
const [, setOutputTempDir] = useAtom(outputTempDirAtom);
const setDialog = useSetAtom(windowMenuDialogAtom);
const setOutputTempDir = useSetAtom(outputTempDirAtom);

const handleConvert = async () => {
const result = await convert(
Expand Down Expand Up @@ -224,13 +224,13 @@ function FileOpen(): React.ReactNode {

function FileRemoveAll(): React.ReactNode {
const [filePaths, setFilePaths] = useAtom(filePathsAtom);
const [tabSelected] = useAtom(tabSelectedAtom);
const [, setFileInfos] = useAtom(fileInfosAtom);
const tabSelected = useAtomValue(tabSelectedAtom);
const setFileInfos = useSetAtom(fileInfosAtom);
const [processedFilePathsSorted, setProcessedFilePathsSorted] = useAtom(
processedFilePathsSortedAtom
);
const [, setCheckboxSelected] = useAtom(checkboxSelectedAtom);
const [, setProcessedFilePaths] = useAtom(processedFilePathsAtom);
const setCheckboxSelected = useSetAtom(checkboxSelectedAtom);
const setProcessedFilePaths = useSetAtom(processedFilePathsAtom);

function removeAll() {
setFilePaths([]);
Expand Down Expand Up @@ -283,8 +283,8 @@ function FileRemoveAll(): React.ReactNode {

function FileSaveAll(): React.ReactNode {
const [isSaving, setIsSaving] = useState(false);
const [processedFilePathsSorted] = useAtom(processedFilePathsSortedAtom);
const [, setDialog] = useAtom(windowMenuDialogAtom);
const processedFilePathsSorted = useAtomValue(processedFilePathsSortedAtom);
const setDialog = useSetAtom(windowMenuDialogAtom);
const handleSaveAll = async () => {
const result = await saveAll(
setIsSaving,
Expand Down Expand Up @@ -323,9 +323,9 @@ function FileSaveAll(): React.ReactNode {

function FileSaveSelected(): React.ReactNode {
const [isSaving, setIsSaving] = useState(false);
const [processedFilePathsSorted] = useAtom(processedFilePathsSortedAtom);
const [checkboxSelected] = useAtom(checkboxSelectedAtom);
const [, setDialog] = useAtom(windowMenuDialogAtom);
const processedFilePathsSorted = useAtomValue(processedFilePathsSortedAtom);
const checkboxSelected = useAtomValue(checkboxSelectedAtom);
const setDialog = useSetAtom(windowMenuDialogAtom);
const handleSaveSelected = async () => {
const result = await saveSelected(
setIsSaving,
Expand Down Expand Up @@ -365,14 +365,14 @@ function FileSaveSelected(): React.ReactNode {

function FileConvert(): React.ReactNode {
const [isProcessing, setIsProcessing] = useAtom(isProcessingAtom);
const [, setProcessedFilePaths] = useAtom(processedFilePathsAtom);
const [, setDialog] = useAtom(windowMenuDialogAtom);
const [filePaths] = useAtom(filePathsAtom);
const [fileInfos] = useAtom(fileInfosAtom);
const [quality] = useAtom(qualityAtom);
const [extensionType] = useAtom(extensionTypeAtom);
const [, setTabSelected] = useAtom(tabSelectedAtom);
const [, setOutputTempDir] = useAtom(outputTempDirAtom);
const setProcessedFilePaths = useSetAtom(processedFilePathsAtom);
const setDialog = useSetAtom(windowMenuDialogAtom);
const filePaths = useAtomValue(filePathsAtom);
const fileInfos = useAtomValue(fileInfosAtom);
const quality = useAtomValue(qualityAtom);
const extensionType = useAtomValue(extensionTypeAtom);
const setTabSelected = useSetAtom(tabSelectedAtom);
const setOutputTempDir = useSetAtom(outputTempDirAtom);
const handleConvert = async () => {
const result = await convert(
setIsProcessing,
Expand Down
Loading