Skip to content

Commit

Permalink
fix default path for game
Browse files Browse the repository at this point in the history
  • Loading branch information
nicanordlc committed May 29, 2024
1 parent fa0a032 commit 07a1df8
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 66 deletions.
31 changes: 5 additions & 26 deletions backend/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"runtime"

"github.com/cabaalexander/save-manager/backend/utils"
rt "github.com/wailsapp/wails/v2/pkg/runtime"
)

Expand All @@ -27,34 +28,12 @@ func (a *App) ToggleFullScreen() {
}
}

func (a *App) OpenDirectoryDialog() string {
path, err := rt.OpenDirectoryDialog(a.ctx, a.getDefaultFileOrDirPath())
if err != nil {
return ""
}
return path
}

func (a *App) OpenFileDialog() string {
path, err := rt.OpenFileDialog(a.ctx, a.getDefaultFileOrDirPath())
if err != nil {
return ""
}
return path
func (a *App) OpenDialogDirApp() (string, error) {
return utils.OpenDialogDir(a.ctx, a.Settings.DefaultSavePath, false)
}

func (a *App) getDefaultFileOrDirPath() rt.OpenDialogOptions {
defaultPath := a.Settings.DefaultSavePath
if a.Settings.JsonSettings.DefaultSavePathIsFile {
return rt.OpenDialogOptions{
DefaultFilename: defaultPath,
Title: "Select File",
}
}
return rt.OpenDialogOptions{
DefaultDirectory: defaultPath,
Title: "Select Directory",
}
func (a *App) OpenDialogFileApp() (string, error) {
return utils.OpenDialogFile(a.ctx, a.Settings.DefaultSavePath, true)
}

func (a *App) GetOS() string {
Expand Down
26 changes: 19 additions & 7 deletions backend/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
)

type GameSingle struct {
ID uuid.UUID
Name string
SavePath string
ID uuid.UUID
Name string
SavePath string
SavePathIsFile bool
}

type JsonGame struct {
Expand All @@ -39,9 +40,9 @@ func (g *Game) Startup(ctx context.Context) {
g.JsonGame = *game
}

func (g *Game) AddGame(name string, savePath string) uuid.UUID {
func (g *Game) AddGame(name, savePath string, isFile bool) uuid.UUID {
id := uuid.New()
game := GameSingle{ID: id, Name: name, SavePath: savePath}
game := GameSingle{ID: id, Name: name, SavePath: savePath, SavePathIsFile: isFile}
g.JsonGame.Data = append(g.JsonGame.Data, game)
g.updateJson()
CreateGameDir(id)
Expand Down Expand Up @@ -81,10 +82,10 @@ func (g *Game) FindGame(id uuid.UUID) GameSingle {
return GameSingle{}
}

func (g *Game) OpenGameDir(gameID uuid.UUID) {
func (g *Game) BrowseGameDir(gameID uuid.UUID) {
for _, game := range g.JsonGame.Data {
if game.ID == gameID {
utils.OpenPath(g.ctx, game.SavePath)
utils.BrowsePath(g.ctx, game.SavePath)
}
}
}
Expand All @@ -99,13 +100,24 @@ func (g *Game) UpdateGame(props GameSingle) {
if props.SavePath != "" {
gm.SavePath = props.SavePath
}
gm.SavePathIsFile = props.SavePathIsFile
}
gameList = append(gameList, gm)
}
g.JsonGame.Data = gameList
g.updateJson()
}

func (g *Game) OpenDialogDirGame(gameID uuid.UUID) (string, error) {
game := g.FindGame(gameID)
return utils.OpenDialogDir(g.ctx, game.SavePath, game.SavePathIsFile)
}

func (g *Game) OpenDialogFileGame(gameID uuid.UUID) (string, error) {
game := g.FindGame(gameID)
return utils.OpenDialogFile(g.ctx, game.SavePath, game.SavePathIsFile)
}

func (g *Game) removeGameDir(gameID uuid.UUID) error {
gameDir, err := GetGameDir(gameID)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion backend/save-quicksave.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (s *Save) OpenQuickSaveDir(gameID uuid.UUID) error {
if err != nil {
return err
}
if err = utils.OpenPath(s.ctx, quickSaveDir); err != nil {
if err = utils.BrowsePath(s.ctx, quickSaveDir); err != nil {
return err
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion backend/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (s *Save) OpenSaveDir(saveID, gameID uuid.UUID) error {
if err != nil {
return err
}
utils.OpenPath(s.ctx, saveDir)
utils.BrowsePath(s.ctx, saveDir)
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions backend/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ func (s *Settings) ReadSettings() (*JsonSettings, error) {
return settingsJson, nil
}

func (s *Settings) SetDefaultSavePath(text string, isFile bool) {
s.JsonSettings.DefaultSavePath = text
func (s *Settings) SetDefaultSavePath(path string, isFile bool) {
s.JsonSettings.DefaultSavePath = path
s.JsonSettings.DefaultSavePathIsFile = isFile
s.updateJson()
}
Expand Down
61 changes: 60 additions & 1 deletion backend/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/fs"
"os"
"path"
"path/filepath"

rt "github.com/wailsapp/wails/v2/pkg/runtime"
)
Expand Down Expand Up @@ -158,7 +159,14 @@ type StartAble interface {
Startup(ctx context.Context)
}

func OpenPath(ctx context.Context, path string) error {
func BrowsePath(ctx context.Context, path string) error {
pathIsFile, err := isPathFile(path)
if err != nil {
return err
}
if pathIsFile {
path = filepath.Dir(path)
}
rt.BrowserOpenURL(ctx, path)
return nil
}
Expand All @@ -170,3 +178,54 @@ func StartApps(l []StartAble) func(ctx context.Context) {
}
}
}

func OpenDialogFile(ctx context.Context, path string, isFile bool) (string, error) {
path, err := rt.OpenFileDialog(ctx, getFileOrDirOptions(path, isFile))
if err != nil {
return "", err
}
return path, nil
}

func OpenDialogDir(ctx context.Context, path string, isFile bool) (string, error) {
pathIsFile, err := isPathFile(path)
if err != nil {
return "", err
}
// if path is a file get parent dir (so this opens a directory efectively)
if pathIsFile {
path = filepath.Dir(path)
}
path, err = rt.OpenDirectoryDialog(
ctx,
getFileOrDirOptions(path, isFile),
)
if err != nil {
return "", err
}
return path, nil
}

func getFileOrDirOptions(path string, isFile bool) rt.OpenDialogOptions {
if isFile {
return rt.OpenDialogOptions{
DefaultFilename: path,
Title: "Select File",
}
}
return rt.OpenDialogOptions{
DefaultDirectory: path,
Title: "Select Directory",
}
}

func isPathFile(path string) (bool, error) {
fileInfo, err := os.Stat(path)
if err != nil {
return false, err
}
if fileInfo.IsDir() {
return false, nil
}
return true, nil
}
1 change: 1 addition & 0 deletions frontend/src/components/AddGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const AddGame = () => {
const gameID = (await addGame({
Name: data.Name,
SavePath: data.SavePath,
SavePathIsFile: data.SavePathIsFile,
})) as string;
navigate(`/game/${gameID}`);
}}
Expand Down
77 changes: 60 additions & 17 deletions frontend/src/components/DialogGameForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
Input,
Typography,
} from "@material-tailwind/react";
import { OpenDirectoryDialog, OpenFileDialog } from "@wailsjs/go/backend/App";
import clsx from "clsx";
import {
type Dispatch,
Expand All @@ -21,28 +20,34 @@ import {
import { type SubmitHandler, useForm } from "react-hook-form";
import { FaDirections } from "react-icons/fa";
import { FaX } from "react-icons/fa6";
import { OpenDialogDirApp, OpenDialogFileApp } from "@wailsjs/go/backend/App";
import {
OpenDialogDirGame,
OpenDialogFileGame,
} from "@wailsjs/go/backend/Game";
import { type GameSingle } from "@/hooks/useGame";
import useSettings from "@/hooks/useSettings";

const TRANSITION_TIMEOUT = 300;

type FormInputs = Pick<GameSingle, "Name" | "SavePath">;
type FormInputs = Pick<GameSingle, "Name" | "SavePath" | "SavePathIsFile">;

type DialogGameFormDefaultValues = {
formInputs: Partial<FormInputs>;
gameID: string;
};

type DialogGameFormProps = {
open: boolean;
handler: Dispatch<SetStateAction<boolean>>;
title: string;
bodyTitle?: string;
required?: Partial<Record<keyof FormInputs, boolean>>;
defaultValues?: Partial<Record<keyof FormInputs, string>>;
defaultValues?: Partial<DialogGameFormDefaultValues>;
submit: (data: FormInputs) => unknown;
};

const DialogGameForm: FC<DialogGameFormProps> = (props) => {
const { querySettings } = useSettings();
const [isFileDialog, setIsFileDialog] = useState<boolean>(
querySettings.data?.DefaultSavePathIsFile ?? false,
);
const {
register,
handleSubmit,
Expand All @@ -53,19 +58,42 @@ const DialogGameForm: FC<DialogGameFormProps> = (props) => {
formState: { errors: formErrors },
} = useForm<FormInputs>();
const { defaultValues } = props;
const { querySettings } = useSettings();

const defaultIsFile =
defaultValues?.formInputs?.SavePathIsFile ??
querySettings.data?.DefaultSavePathIsFile ??
false;

const [isFileDialog, setIsFileDialog] = useState<boolean>(defaultIsFile);

const onSubmit: SubmitHandler<FormInputs> = (data) => props.submit(data);

const handlePath = async () => {
const path = isFileDialog
? await OpenFileDialog()
: await OpenDirectoryDialog();
let path = "";

if (defaultValues?.formInputs?.SavePath === "") {
path = isFileDialog
? await OpenDialogFileApp()
: await OpenDialogDirApp();
} else {
path = isFileDialog
? await OpenDialogFileGame(defaultValues?.gameID)
: await OpenDialogDirGame(defaultValues?.gameID);
}

if (path === "") return;

setValue("SavePath", path);
clearErrors("SavePath");
setFocus("Name");
};

const handleIsFile = () => {
setIsFileDialog(!isFileDialog);
setValue("SavePathIsFile", !isFileDialog);
};

useEffect(() => {
if (props.open) {
setTimeout(() => {
Expand All @@ -75,13 +103,17 @@ const DialogGameForm: FC<DialogGameFormProps> = (props) => {
});

useEffect(() => {
if (defaultValues) {
Object.entries(defaultValues).forEach(([key, value]) => {
if (defaultValues?.formInputs) {
Object.entries(defaultValues.formInputs).forEach(([key, value]) => {
setValue(key as keyof FormInputs, value);
});
}
}, [defaultValues, setValue]);

useEffect(() => {
setIsFileDialog(defaultIsFile);
}, [defaultIsFile]);

const toggleDialog = () => {
props.handler(!props.open);
setTimeout(() => {
Expand Down Expand Up @@ -151,11 +183,15 @@ const DialogGameForm: FC<DialogGameFormProps> = (props) => {

<Checkbox
checked={isFileDialog}
onChange={() => {
setIsFileDialog(!isFileDialog);
}}
onChange={handleIsFile}
label="File"
/>
<input
className="hidden"
{...register("SavePathIsFile", {
required: props.required?.SavePathIsFile,
})}
/>
</div>
</div>
</DialogBody>
Expand All @@ -166,7 +202,8 @@ const DialogGameForm: FC<DialogGameFormProps> = (props) => {
</Button>

<Button type="submit" variant="gradient" color="gray">
Create Game
{defaultValues?.formInputs?.SavePath === "" ? "CREATE" : "SAVE"}
<span> GAME</span>
</Button>
</DialogFooter>
</form>
Expand All @@ -177,7 +214,13 @@ const DialogGameForm: FC<DialogGameFormProps> = (props) => {
DialogGameForm.defaultProps = {
bodyTitle: "",
required: { Name: false, SavePath: false },
defaultValues: { Name: "", SavePath: "" },
defaultValues: {
formInputs: {
Name: "",
SavePath: "",
},
gameID: "",
},
};

export default DialogGameForm;
Loading

0 comments on commit 07a1df8

Please sign in to comment.