Skip to content

Commit 99dc001

Browse files
feat: implement auto-disable new mods feature and update related components
close #20
1 parent fb2238e commit 99dc001

File tree

10 files changed

+67
-8
lines changed

10 files changed

+67
-8
lines changed

resources/dist.rc

281 Bytes
Binary file not shown.

src/aria2c.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ pub fn download_file_with_progress_ureq(
105105
}
106106
}
107107
progress_callback(DownloadCallbackInfo { progress: 100.0 });
108-
std::fs::rename(&tmp_path, output_path)?;
108+
std::fs::copy(&tmp_path, output_path)?;
109+
std::fs::remove_file(&tmp_path)?;
109110
Ok(())
110111
}
111112

src/blacklist.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub struct ModBlacklist {
1414

1515
#[derive(Debug, Serialize, Deserialize)]
1616
pub struct ModBlacklistProfile {
17-
name: String,
18-
mods: Vec<ModBlacklist>,
17+
pub name: String,
18+
pub mods: Vec<ModBlacklist>,
1919
}
2020

2121
pub fn apply_mod_blacklist_profile(

src/celemod-ui/src/components/ModList.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import InfiniteLoader from 'react-window-infinite-loader';
1313
import { memo } from 'preact/compat';
1414
import { Content } from '../api/wegfan';
1515
import { Download } from '../context/download';
16+
import { useAutoDisableNewMods } from '../states';
1617
import { useGlobalContext } from '../App';
1718
import { PopupContext, createPopup } from './Popup';
1819
import { ProgressIndicator } from './Progress';
@@ -71,6 +72,7 @@ export const Mod = memo(
7172
isInstalled: boolean;
7273
}) => {
7374
const { download, modManage } = useGlobalContext();
75+
const [autoDisableNewMods] = useAutoDisableNewMods();
7476
const { mod } = props;
7577
const preview = mod.previewUrl;
7678

@@ -92,6 +94,7 @@ export const Mod = memo(
9294
const down = (name: string, fileid: string) => {
9395
setDownloadTask(
9496
download.downloadMod(name, fileid, {
97+
autoDisableNewMods,
9598
onProgress: (task) => setDownloadTask({ ...task }),
9699
onFailed: (task) => setDownloadTask({ ...task }),
97100
onFinished: (task) => {

src/celemod-ui/src/context/download.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export const createDownloadContext = () => {
7878
downloadTasks,
7979
downloadMod: (name: string, gb_fileid_or_url: string, {
8080
force = false,
81+
autoDisableNewMods = false,
8182
onProgress = (task: Download.TaskInfo, progress: number) => { },
8283
onFinished = (task: Download.TaskInfo) => { },
8384
onFailed = (task: Download.TaskInfo, error: string) => { }
@@ -124,7 +125,7 @@ export const createDownloadContext = () => {
124125

125126
eventBus.dispatchEvent('taskListChanged')
126127

127-
callRemote("download_mod", name, url, gamePath + "/Mods/", (_subtasks: string, state: "pending" | "failed" | "finished") => {
128+
callRemote("download_mod", name, url, gamePath + "/Mods/", autoDisableNewMods, (_subtasks: string, state: "pending" | "failed" | "finished") => {
128129
console.log(_subtasks, state)
129130
const subtasks = JSON.parse(_subtasks) as BackendDownloadInfo[];
130131
const task = downloadTasks.current[name];

src/celemod-ui/src/routes/Manage.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
BackendDep,
66
BackendModInfo,
77
useAlwaysOnMods,
8+
useAutoDisableNewMods,
89
useCurrentBlacklistProfile,
910
useGamePath,
1011
useInstalledMods,
@@ -66,6 +67,7 @@ const modListContext = createContext<{
6667
showUpdate: boolean;
6768
alwaysOnMods: string[];
6869
switchAlwaysOn: (name: string, enabled: boolean) => void;
70+
autoDisableNewMods: boolean;
6971
hasUpdateMods: {
7072
name: string;
7173
version: string;
@@ -134,6 +136,7 @@ const ModMissing = ({ name, version, optional }: MissingModDepInfo) => {
134136
? async () => {
135137
setState(_i18n.t('下载中'));
136138
download.downloadMod(name, gbFileID, {
139+
autoDisableNewMods: ctx?.autoDisableNewMods || false,
137140
onProgress: (task, progress) => {
138141
setState(`${progress}% (${task.subtasks.length})`);
139142
},
@@ -416,6 +419,7 @@ export const Manage = () => {
416419
const noEverest = enforceEverest();
417420
if (noEverest) return noEverest;
418421
const [alwaysOnMods, setAlwaysOnMods] = useAlwaysOnMods();
422+
const [autoDisableNewMods, setAutoDisableNewMods] = useAutoDisableNewMods();
419423
const [gamePath] = useGamePath();
420424
const modPath = gamePath + '/Mods';
421425

@@ -701,6 +705,7 @@ export const Manage = () => {
701705
else setAlwaysOnMods(alwaysOnMods.filter((v) => v !== name));
702706
},
703707
alwaysOnMods,
708+
autoDisableNewMods,
704709
modComments, setModComment(name: string, comment: string) {
705710
setModComments({
706711
...modComments,
@@ -972,6 +977,18 @@ export const Manage = () => {
972977

973978
{_i18n.t('显示更新')}
974979
</label>
980+
<label>
981+
<input
982+
type="checkbox"
983+
checked={autoDisableNewMods}
984+
onChange={(e) => {
985+
// @ts-ignore
986+
setAutoDisableNewMods(e.target.checked);
987+
}}
988+
/>
989+
990+
{_i18n.t('自动禁用新安装的Mod')}
991+
</label>
975992
</div>
976993
<div
977994
className="opers"
@@ -992,6 +1009,7 @@ export const Manage = () => {
9921009
mod.name,
9931010
mod.gb_file === '-1' ? mod.url : mod.gb_file,
9941011
{
1012+
autoDisableNewMods: manageCtx.autoDisableNewMods,
9951013
onProgress: (task, progress) => {
9961014
console.log(task, progress);
9971015
},

src/celemod-ui/src/routes/RecommendMaps.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import theRoadLessTravelledImg from '../resources/collabs/the-road-less-travelle
1616
import { callRemote, horizontalScrollMouseWheelHandler } from 'src/utils';
1717
import { Button } from 'src/components/Button';
1818
import { memo } from 'preact/compat';
19-
import { useInstalledMods } from 'src/states';
19+
import { useAutoDisableNewMods, useInstalledMods } from 'src/states';
2020
import { useState } from 'react';
2121
import { useGlobalContext } from 'src/App';
2222

@@ -25,6 +25,7 @@ export const RecommendMaps = () => {
2525
// if (noEverest) return noEverest;
2626

2727
const { installedMods } = useInstalledMods();
28+
const [autoDisableNewMods] = useAutoDisableNewMods();
2829
const ctx = useGlobalContext();
2930
const InstallButton = ({ name, url }) => {
3031
const installed = installedMods.some((mod) => mod.name === name);
@@ -42,6 +43,7 @@ export const RecommendMaps = () => {
4243
name,
4344
parseInt(gbFileId) === -1 ? url : gbFileId,
4445
{
46+
autoDisableNewMods,
4547
onProgress(task, progress) {
4648
setState(
4749
`${progress}% (${

src/celemod-ui/src/routes/RecommendMods.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _i18n, { useI18N } from 'src/i18n';
22
import './RecommendMods.scss';
33
import { h } from 'preact';
4-
import { useGamePath, useInstalledMods } from '../states';
4+
import { useAutoDisableNewMods, useGamePath, useInstalledMods } from '../states';
55
import { Mod } from '../components/ModList';
66
import { Button } from '../components/Button';
77
import { useState, useEffect } from 'react';
@@ -22,13 +22,15 @@ const RMod = ({
2222
installed,
2323
startDownloadHandler,
2424
modsFolder,
25+
autoDisableNewMods,
2526
}: {
2627
name: string;
2728
download_url: string;
2829
description: string;
2930
installed?: boolean;
3031
startDownloadHandler?: any;
3132
modsFolder?: string;
33+
autoDisableNewMods: boolean;
3234
}) => {
3335
const [state, setState] = useState(
3436
installed ? _i18n.t('已安装') : _i18n.t('下载')
@@ -43,6 +45,7 @@ const RMod = ({
4345
if (!!data) {
4446
const [gbFileId, version] = JSON.parse(data);
4547
ctx.download.downloadMod(name, parseInt(gbFileId) === -1 ? download_url : gbFileId, {
48+
autoDisableNewMods,
4649
onProgress(task, progress) {
4750
setState(
4851
`${progress}% (${task.subtasks.filter((v) => v.state === 'Finished').length
@@ -92,6 +95,7 @@ export const RecommendMods = () => {
9295
const skinMods = _skinMods()
9396

9497
const { installedMods } = useInstalledMods();
98+
const [autoDisableNewMods] = useAutoDisableNewMods();
9599
const [gamePath] = useGamePath();
96100
const modsPath = gamePath + '/Mods';
97101
const refDownloadHandlers = useRef(
@@ -138,6 +142,7 @@ export const RecommendMods = () => {
138142
download_url={mod.download_url}
139143
description={mod.description}
140144
modsFolder={modsPath}
145+
autoDisableNewMods={autoDisableNewMods}
141146
installed={installedMods.some(
142147
(m) => m.name === modNameFromUrl(mod.download_url)
143148
)}
@@ -154,6 +159,7 @@ export const RecommendMods = () => {
154159
download_url={mod.download_url}
155160
description={mod.description}
156161
modsFolder={modsPath}
162+
autoDisableNewMods={autoDisableNewMods}
157163
startDownloadHandler={
158164
// @ts-ignore
159165
refDownloadHandlers.current[mod.name]

src/celemod-ui/src/states.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,6 @@ export const [initAlwaysOnMods, useAlwaysOnMods] = createPersistedStateByKey('al
164164

165165
export const [initSearchSort, useSearchSort] = createPersistedStateByKey<'new' | 'updateAdded' | 'updated' | 'views' | 'likes'>('searchSort', 'likes')
166166

167+
export const [initAutoDisableNewMods, useAutoDisableNewMods] = createPersistedStateByKey('autoDisableNewMods', false)
168+
167169
export const [initModComments, useModComments] = createPersistedStateByKey('modComments', {})

src/main.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ fn get_celestes() -> Vec<Game> {
299299
games
300300
}
301301

302-
#[derive(Serialize, Deserialize, Debug, Clone)]
302+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
303303
enum DownloadStatus {
304304
Waiting,
305305
Downloading,
@@ -326,6 +326,7 @@ impl Handler {
326326
name: String,
327327
url: String,
328328
mods_dir: String,
329+
auto_disable_new_mods: bool,
329330
callback: sciter::Value,
330331
_use_cn_proxy: bool,
331332
multi_thread: bool,
@@ -452,6 +453,31 @@ impl Handler {
452453
}
453454
}
454455

456+
// Auto-disable new mods if enabled
457+
if auto_disable_new_mods {
458+
let game_path = Path::new(&mods_dir).parent().unwrap().to_str().unwrap().to_string();
459+
let profiles = blacklist::get_mod_blacklist_profiles(&game_path);
460+
let mut new_mods = vec![];
461+
for task in tasklist.borrow().iter() {
462+
if task.status == DownloadStatus::Finished {
463+
new_mods.push(task.name.clone());
464+
}
465+
}
466+
if !new_mods.is_empty() {
467+
let installed_mods = get_installed_mods_sync(mods_dir.clone());
468+
let mods_to_disable: Vec<(&String, &String)> = new_mods.iter()
469+
.filter_map(|name| {
470+
installed_mods.iter().find(|m| m.name == *name).map(|m| (&m.name, &m.file))
471+
})
472+
.collect();
473+
if !mods_to_disable.is_empty() {
474+
for profile in profiles {
475+
blacklist::switch_mod_blacklist_profile(&game_path, &profile.name, mods_to_disable.clone(), false)?;
476+
}
477+
}
478+
}
479+
}
480+
455481
println!("Download finished");
456482

457483
post_callback(&tasklist.borrow(), "finished");
@@ -793,7 +819,7 @@ impl Handler {
793819

794820
impl sciter::EventHandler for Handler {
795821
dispatch_script_call! {
796-
fn download_mod(String, String, String, Value, bool, bool);
822+
fn download_mod(String, String, String, bool, Value, bool, bool);
797823
fn get_celeste_dirs();
798824
fn get_installed_mod_ids(String, Value);
799825
fn get_installed_mods(String, Value);

0 commit comments

Comments
 (0)