diff --git a/src/components/appcontext.tsx b/src/components/appcontext.tsx index 023ee80..8a1fcc2 100644 --- a/src/components/appcontext.tsx +++ b/src/components/appcontext.tsx @@ -176,11 +176,13 @@ export const AppProvider = (props: React.PropsWithChildren) => { } const updateWinchConfig = () => { - invoke("update_winch_config", { - "json": JSON.stringify(state.winchConfig, null, 2), - dredgePath: state.dredgePath}) - .then(reloadMods) - .catch(genericHandleError); + if (state.winchConfig != null) { + invoke("update_winch_config", { + "json": JSON.stringify(state.winchConfig, null, 2), + dredgePath: state.dredgePath}) + .then(reloadMods) + .catch(genericHandleError); + } } // fetch dredge path on mount diff --git a/src/components/content.tsx b/src/components/content.tsx index c76ed7f..71a9828 100644 --- a/src/components/content.tsx +++ b/src/components/content.tsx @@ -1,18 +1,24 @@ -import React, {useContext} from 'react' +import React, {useContext, useState} from 'react' import '../scss/content.scss' import { Mods } from './mods/Mods' import {default as Settings} from './settings/settings' import {AppContext} from "./appcontext"; +import {SortDirection, SortField, SortType} from "./mods/SortField"; export const Content = () => { const {state} = useContext(AppContext) + const [searchQuery, setSearchQuery] = useState("") + const [sortField, setSortField] = useState(SortType.DEFAULT); + const [sortDirection, setSortDirection] = useState(SortDirection.ASCENDING); + const content_options = new Map( [ - ["Mods", ], + ["Mods", ], ["Settings", ] ] ) diff --git a/src/components/mods/AvailableMod.tsx b/src/components/mods/AvailableMod.tsx index 4f062aa..35a4602 100644 --- a/src/components/mods/AvailableMod.tsx +++ b/src/components/mods/AvailableMod.tsx @@ -21,8 +21,9 @@ export const AvailableMod = (props: IModProps) => { const [ installed, setInstalled] = useState(false); let installText = "Install" + // It'll only show on the Available page as "installed" as its actively installing if (installed) { - installText = "Installed" + installText = "Installing..." } return
@@ -30,6 +31,13 @@ export const AvailableMod = (props: IModProps) => { + + + @@ -38,13 +46,7 @@ export const AvailableMod = (props: IModProps) => { - - - +
diff --git a/src/components/mods/ModList.tsx b/src/components/mods/ModList.tsx index 2dd7579..1ae2cf4 100644 --- a/src/components/mods/ModList.tsx +++ b/src/components/mods/ModList.tsx @@ -8,13 +8,11 @@ import {ModsNotFound} from "./ModsNotFound"; import {Search} from "./SearchField"; import {SortDirection, SortField, SortType} from "./SortField"; -export const ModList = (props: {selected: string}) => { +export const ModList = (props: {selected: string, searchQuery: string, setSearchQuery: (selected: string) => void, + sortField : SortType, setSortField: (selected : SortType) => void, + sortDirection : SortDirection, setSortDirection: (selected : SortDirection) => void +}) => { const context = useContext(AppContext) - - const [searchQuery, setSearchQuery] = useState(""); - const [sortField, setSortField] = useState(SortType.DEFAULT); - const [sortDirection, setSortDirection] = useState(SortDirection.ASCENDING); - const defaultSortField = SortType.MOD_NAME; // https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate @@ -26,16 +24,6 @@ export const ModList = (props: {selected: string}) => { debouncedForceUpdate() }, []) - useEffect(() => { - setSearchQuery(""); - setSortField(SortType.DEFAULT); - setSortDirection(SortDirection.DESCENDING); - }, [props.selected]); - - useEffect(() => { - console.log(sortField, sortDirection) - }, [sortField, sortDirection]); - const uninstallMod = (path: string) => { context!.uninstallMod(path) debouncedForceUpdate() @@ -68,7 +56,7 @@ export const ModList = (props: {selected: string}) => { query = query.toLowerCase(); - if (searchQuery === "" || searchQuery === undefined) { + if (props.searchQuery === "" || props.searchQuery === undefined) { return mods; } @@ -180,7 +168,7 @@ export const ModList = (props: {selected: string}) => { if (props.selected === "Installed") { // not keen on cyclic dependency of IEnabledStruct, but also want to avoid usage of 'any' in sortMod // so casting to exact same definition as IEnabledStruct to use - const filteredMods = filterSortMods(modList, searchQuery, sortField, sortDirection); + const filteredMods = filterSortMods(modList, props.searchQuery, props.sortField, props.sortDirection); installedList = filteredMods.map((mod) => { return { } if (props.selected === "Available") { - const filteredMods = filterSortMods(database!, searchQuery, sortField, sortDirection); + const filteredMods = filterSortMods(database!, props.searchQuery, props.sortField, props.sortDirection); availableList = filteredMods.map((mod) => { if (!info!.has(mod.ModGUID)) { return { ] } return <>
- - + +
{shownList} diff --git a/src/components/mods/Mods.tsx b/src/components/mods/Mods.tsx index cfb383e..51d4ec5 100644 --- a/src/components/mods/Mods.tsx +++ b/src/components/mods/Mods.tsx @@ -5,8 +5,13 @@ import '../../scss/mods/mods.scss' import { ModsTab } from "./ModsTab" import { ModList } from "./ModList" +import {SortDirection, SortField, SortType} from "./SortField"; -export const Mods = (props: {selected: string}) => { + +export const Mods = (props: {selected: string, searchQuery: string, setSearchQuery: (selected: string) => void, + sortField : SortType, setSortField: (selected : SortType) => void, + sortDirection : SortDirection, setSortDirection: (selected : SortDirection) => void +}) => { const [selectedTab, setSelectedTab] = useState(props.selected) return
@@ -16,7 +21,8 @@ export const Mods = (props: {selected: string}) => {
- +
} \ No newline at end of file diff --git a/src/components/mods/SearchField.tsx b/src/components/mods/SearchField.tsx index 41881d4..74cd847 100644 --- a/src/components/mods/SearchField.tsx +++ b/src/components/mods/SearchField.tsx @@ -26,5 +26,12 @@ export const Search = (props: ISearchProps) => { onChange={(e) => { setText(e.currentTarget.value); }}/> + { text === "" ? "" : + + } } \ No newline at end of file diff --git a/src/components/settings/settings.tsx b/src/components/settings/settings.tsx index 096e164..dba06c6 100644 --- a/src/components/settings/settings.tsx +++ b/src/components/settings/settings.tsx @@ -14,8 +14,17 @@ export const Settings = (props: {path_correct?: boolean}) => { const context = useContext(AppContext); + const [shouldCheckWinchConfig, setshouldCheckWinchConfig] = useState(true); const [path, setPath] = useState(""); + // Opening the settings tab will try reloading everything: Checks if winch config has been setup by the modloader yet + useEffect(() => { + if (context.state.winchConfig == null && shouldCheckWinchConfig) { + context?.reloadMods() + } + setshouldCheckWinchConfig(false); + }); + // Fetch DREDGE path from context; only called once on load useEffect(() => { if (path === "") { @@ -60,7 +69,7 @@ export const Settings = (props: {path_correct?: boolean}) => { context?.updateWinchConfig() } - const pathWarning = props.path_correct ? "" :
Invalid DREDGE path
+ const pathWarning = props.path_correct ? "" :
Invalid DREDGE path
const dredgeFolderButton = !props.path_correct ? "" : <>
@@ -109,7 +118,6 @@ export const Settings = (props: {path_correct?: boolean}) => { onChange={(e) => { const value = e.target.value; setPath(value); - }} value={path} /> @@ -118,10 +126,25 @@ export const Settings = (props: {path_correct?: boolean}) => { {pathWarning} {dredgeFolderButton}
- {config ? configOptions : ""} + {config ? configOptions : + + Run DREDGE with the Winch modloader at least once to enable settings. + }
+ +
Dredge Mod Manager version {appVersion}
diff --git a/src/scss/mods/modsAvailableInstalled.scss b/src/scss/mods/modsAvailableInstalled.scss index 789d428..1fda0ae 100644 --- a/src/scss/mods/modsAvailableInstalled.scss +++ b/src/scss/mods/modsAvailableInstalled.scss @@ -8,6 +8,31 @@ position: relative; + .interact-buttons { + display: flex; + flex-direction: row; + gap: 10px; + margin-right: auto; + } + + .interact-button { + color: $text-light-primary; + font-weight: 500; + border: 2px solid $bg-primary-tint; + border-radius: 5px; + width: 90px; + height: 32px; + margin-left: 2px; + margin-right: 2px; + + transition: background-color 100ms ease, + border-color 100ms ease; + + &:hover { + background-color: $bg-primary-tint; + } + } + .box-primary-container { padding: 0 10px; display: flex; @@ -193,28 +218,6 @@ gap: 10px; margin: 0 10px 5px 10px; - .interact-buttons { - display: flex; - flex-direction: row; - gap: 10px; - margin-right: auto; - } - - .interact-button { - color: $text-light-primary; - font-weight: 500; - border: 2px solid $bg-primary-tint; - border-radius: 5px; - width: 90px; - - transition: background-color 100ms ease, - border-color 100ms ease; - - &:hover { - background-color: $bg-primary-tint; - } - } - .interact-icons { display: flex; flex-direction: row-reverse; diff --git a/src/scss/settings.scss b/src/scss/settings.scss index 8917657..bb4a94c 100644 --- a/src/scss/settings.scss +++ b/src/scss/settings.scss @@ -24,6 +24,22 @@ background: $bg-primary; } + .settings-links + { + font-size: 30px; + i { + width: 32px; + } + a { + margin-left: 4px; + margin-right: 4px; + color: $text-light-primary; + text-align: center; + &:hover { + color: $text-light-secondary; + } + } + } .setting { display: flex; @@ -71,7 +87,13 @@ .warning { font-weight: 600; font-size: 1.2em; - color: $interact-red; + color: yellow; + } + + .error { + font-weight: 600; + font-size: 1.2em; + color: red; } } } \ No newline at end of file