Skip to content

Commit

Permalink
Added "badge" to highlighted newly added plugins
Browse files Browse the repository at this point in the history
This is done upon mod installation.

part of Nexus-Mods/Vortex#15929
  • Loading branch information
IDCs committed Jun 20, 2024
1 parent b08d5df commit e44c35e
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 18 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.3.0] - 2024-06-20

- Added a plugin counter "badge" to the plugins page button for when new plugins
are added as part of a mod installation.

## [0.2.9] - 2024-03-14

- Fixed long delays when ascertaining if a plugin is marked light
Expand Down
3 changes: 3 additions & 0 deletions src/actions/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ export const setPluginFilePath =
export const updatePluginWarnings = createAction('UPDATE_PLUGIN_WARNING',
(id: string, warning: string, value: boolean) => ({ id, warning, value }),
uiOnlyMeta);

export const incrementNewPluginCounter = createAction('INCREMENT_NEW_PLUGIN_COUNTER', (counter: number) => ({ counter }));
export const clearNewPluginCounter = createAction('CLEAR_NEW_PLUGIN_COUNTER');
23 changes: 18 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
import { setPluginEnabled, setPluginOrder, updatePluginOrder } from './actions/loadOrder';
import { setPluginFilePath, setPluginList, updatePluginWarnings } from './actions/plugins';
import { clearNewPluginCounter, incrementNewPluginCounter, setPluginFilePath, setPluginList, updatePluginWarnings } from './actions/plugins';
import { removeGroupRule, setGroup } from './actions/userlist';
import { openGroupEditor, setCreateRule } from './actions/userlistEdit';
import { loadOrderReducer } from './reducers/loadOrder';
Expand Down Expand Up @@ -361,8 +361,11 @@ function register(context: IExtensionContextExt,
));
});

const installedPlugins = () => enabledPlugins(context.api.store.getState())
const pluginCounter = new util.ReduxProp(context.api, [
['session', 'plugins', 'newlyAddedPlugins'],
], (value: number) => (value > 0) ? value : undefined);

const installedPlugins = () => enabledPlugins(context.api.store.getState())
context.registerMainPage('plugins', 'Plugins', PluginList, {
id: 'gamebryo-plugins',
hotkey: 'E',
Expand All @@ -389,6 +392,7 @@ function register(context: IExtensionContextExt,
onSetPluginLight: setPluginLight,
}),
activity: pluginActivity,
badge: pluginCounter,
});

for (const gameId of supportedGames()) {
Expand Down Expand Up @@ -1315,6 +1319,13 @@ function init(context: IExtensionContextExt) {
initGameSupport(context.api).then(() => null);
});

context.api.onStateChange(['session', 'base', 'mainPage'], (previous, current) => {
if (previous !== current && current === 'gamebryo-plugins') {
// TODO: We could theoretically apply filters here to display the plugins that were added.
context.api.store.dispatch(clearNewPluginCounter());
}
});

context.api.events.on('set-plugin-list', (newPlugins: string[], setEnabled?: boolean) => {
const state = context.api.store.getState();
store.dispatch(updatePluginOrder(
Expand Down Expand Up @@ -1401,11 +1412,13 @@ function init(context: IExtensionContextExt) {
path.extname(fileName).toLowerCase()) !== -1)
.map(fileName => path.basename(fileName, GHOST_EXT));
if (plugins.length === 1) {
context.api.store.dispatch(setPluginEnabled(plugins[0], true));
const batched = [setPluginEnabled(plugins[0], true), incrementNewPluginCounter(1)];
util.batchDispatch(context.api.store, batched);
} else if (plugins.length > 1) {
if (mod.attributes?.enableallplugins === true) {
plugins.forEach(plugin => context.api.store.dispatch(
setPluginEnabled(plugin, true)));
const batched: any = plugins.map(plugin => setPluginEnabled(plugin, true));
batched.push(incrementNewPluginCounter(batched.length));
util.batchDispatch(context.api.store, batched);
} else {
notifyMultiplePlugins(context.api, mod, currentProfile, plugins);
}
Expand Down
19 changes: 9 additions & 10 deletions src/reducers/loadOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ import {types, util} from 'vortex-api';
*/
export const loadOrderReducer: types.IReducerSpec = {
reducers: {
[actions.setPluginEnabled as any]:
(state, payload) => {
return (state[payload.pluginName] !== undefined)
? util.setSafe(state, [payload.pluginName.toLowerCase(), 'enabled'], payload.enabled)
: util.merge(state, [payload.pluginName.toLowerCase()], {
name: payload.pluginName,
enabled: payload.enabled,
loadOrder: -1,
});
},
[actions.setPluginEnabled as any]: (state, payload) => {
return (state[payload.pluginName] !== undefined)
? util.setSafe(state, [payload.pluginName.toLowerCase(), 'enabled'], payload.enabled)
: util.merge(state, [payload.pluginName.toLowerCase()], {
name: payload.pluginName,
enabled: payload.enabled,
loadOrder: -1,
});
},
[actions.setPluginOrder as any]: (state, payload) => {
const { plugins, defaultEnable } = payload;
const result = {};
Expand Down
9 changes: 7 additions & 2 deletions src/reducers/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ export const pluginsReducer: types.IReducerSpec = {
},
[actions.updatePluginWarnings as any]: (state, payload) =>
(state.pluginList[payload.id] !== undefined)
? util.setSafe(state, ['pluginList', payload.id, 'warnings', payload.warning], payload.value)
: state,
? util.setSafe(state, ['pluginList', payload.id, 'warnings', payload.warning], payload.value)
: state,
[actions.incrementNewPluginCounter as any]: (state, payload) =>
util.setSafe(state, ['newlyAddedPlugins'], util.getSafe(state, ['newlyAddedPlugins'], 0) + payload.counter),
[actions.clearNewPluginCounter as any]: (state) =>
util.setSafe(state, ['newlyAddedPlugins'], 0)
},
defaults: {
pluginList: {},
pluginInfo: {},
newlyAddedPlugins: 0,
},
};
4 changes: 3 additions & 1 deletion src/views/PluginList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable max-lines-per-function */
import { setPluginEnabled } from '../actions/loadOrder';
import { setPluginInfo, updatePluginWarnings } from '../actions/plugins';
import { clearNewPluginCounter, setPluginInfo, updatePluginWarnings } from '../actions/plugins';
import { setAutoSortEnabled } from '../actions/settings';
import { addGroup, addGroupRule, setGroup } from '../actions/userlist';
import { IESPFile } from '../types/IESPFile';
Expand Down Expand Up @@ -97,6 +97,7 @@ interface IActionProps {
onSetGroup: (pluginName: string, group: string) => void;
onUpdateWarnings: (id: string, warning: string, value: boolean) => void;
onUpdatePluginInfo: (info: { [id: string]: IPluginCombined }) => void;
onClearNewPluginCounter: () => void;
}

interface IComponentState {
Expand Down Expand Up @@ -1503,6 +1504,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch<any, null, Redux.Action>): I
dispatch(updatePluginWarnings(pluginName, notificationId, value)),
onUpdatePluginInfo: (info: { [id: string]: IPluginCombined }) =>
dispatch(setPluginInfo(info)),
onClearNewPluginCounter: () => dispatch(clearNewPluginCounter())
};
}

Expand Down

0 comments on commit e44c35e

Please sign in to comment.