Skip to content

Commit

Permalink
category rework
Browse files Browse the repository at this point in the history
  • Loading branch information
cbartondock committed Jun 19, 2024
1 parent ea06f14 commit 54454f6
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 108 deletions.
141 changes: 60 additions & 81 deletions src/lib/category-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,44 +78,69 @@ export class CategoryManager {
await cats.close();
}
}

removeAllCategoriesAndWrite(steamDirectory: string, userId: string) {
return this.doCatTask(steamDirectory, userId, (collections, sharedConfigApps, levelCollections, cats) => {
return new Promise<any>((resolve, reject) => {
const localKeys = Object.keys(collections);
const levelKeys = Object.keys(levelCollections)
const srmKeys = _.union(localKeys, levelKeys).filter(catKey=>catKey.startsWith('srm'))
const srmCatNames = levelKeys.map(levelKey=>levelCollections[levelKey].name)
// Nuke the local categories
for(const catKey of srmKeys) {
if(catKey.startsWith('srm')) {
// local collections (non steam games)
delete collections[catKey]
// level collections (steam games)
if(levelCollections[catKey] && levelCollections[catKey].added.length == 0) {
cats.remove(catKey);
}
}
// toRemove is assumed to be a subset of the keys of addedCategories.
removeShortsFromCats(toRemove: string[],
collections: any,
levelCollections: any,
cats: any,
sharedConfigApps: any,
addedCategories: VDF_AddedCategoriesData[string][string]) {
const localKeys = Object.keys(collections);
const levelKeys = Object.keys(levelCollections);
// Clean out local collections
for (const catKey of localKeys) {
// only clear out apps that list the category of the collection
const toRemoveForCat = toRemove.filter((shortId)=>{
const appCats = addedCategories[shortId];
const lcCatName = levelCollections[catKey]?.name || "";
return appCats.map((catName: string) => catName.toUpperCase()).includes(lcCatName.toUpperCase());
});
const nonSRMAdded = collections[catKey].added.filter((appId: number) => !toRemoveForCat.map((x)=>+x).includes(appId));
collections[catKey].added = nonSRMAdded;
if(catKey.startsWith('srm') && nonSRMAdded.length == 0) {
delete collections[catKey]
// only remove the level collection if newAdded is empty *and* the level collection itself is empty
if(levelCollections[catKey] && levelCollections[catKey].added.length==0) {
cats.remove(catKey);
}
// Nuke the sharedconfig
// Currently removes only based on the categories, not the ids
// so a non srm id added to an srm category will still have its srm category removed (unlike for local)
for(const sharedConfigId in sharedConfigApps) {
const sharedConfigCats = Object.values(sharedConfigApps[sharedConfigId].tags||{})
const sharedConfigCatsWithoutAdded = sharedConfigCats.filter((scCatName: string)=> {
return !(srmCatNames.map((catName: string) => catName.toUpperCase()).includes(scCatName.toUpperCase()))
})
}
}
//Get the ones in levelCollection that we missed
for (const catKey of levelKeys) {
if(catKey.startsWith('srm') && !collections[catKey] && levelCollections[catKey].added.length == 0) {
cats.remove(catKey);
}
}
//Clean out the sharedconfig
for(const sharedConfigId in sharedConfigApps) {
if(toRemove.includes(sharedConfigId) && sharedConfigApps[sharedConfigId]) {
const sharedConfigCats = Object.values(sharedConfigApps[sharedConfigId].tags||{})
const appCats = addedCategories[sharedConfigId];
const sharedConfigCatsWithoutAdded = appCats ? sharedConfigCats.filter((scCatName: string)=> {
return !(appCats.map((catName: string) => catName.toUpperCase()).includes(scCatName.toUpperCase()))
}) : sharedConfigCats;
if(sharedConfigCatsWithoutAdded.length) {
const formattedAsTags = Object.fromEntries(sharedConfigCatsWithoutAdded.map((catName: string, i: number)=> {
return [i.toString(), catName]
}))
if(sharedConfigCatsWithoutAdded.length) {
sharedConfigApps[sharedConfigId].tags = formattedAsTags;
} else {
delete sharedConfigApps[sharedConfigId];
}
sharedConfigApps[sharedConfigId].tags = formattedAsTags;
} else {
delete sharedConfigApps[sharedConfigId];
}
}
}
}

removeAllCategoriesAndWrite(steamDirectory: string, userId: string, addedCategories: VDF_AddedCategoriesData[string][string]) {
return this.doCatTask(steamDirectory, userId, (collections, sharedConfigApps, levelCollections, cats, data) => {
const { addedCategories } = data;
return new Promise<any>((resolve, reject) => {
const toRemove = Object.keys(addedCategories);
this.removeShortsFromCats(toRemove, collections, levelCollections, cats, sharedConfigApps, addedCategories);
resolve([collections, sharedConfigApps]);
})
}, {
addedCategories: addedCategories
})
}

Expand Down Expand Up @@ -155,56 +180,10 @@ export class CategoryManager {
const {userData, extraneousShortIds, addedCategories} = data;
return new Promise<any>((resolve, reject) => {
const appIds = Object.keys(userData.apps).filter(appId => !superTypes[ArtworkOnlyType].includes(userData.apps[appId].parserType));
const toRemove = _.union(
appIds.map((x) => steam.shortenAppId(x)),
extraneousShortIds
);
// Clean out local collections
for (const catKey of Object.keys(collections)) {
// only clear out apps that list the category of the collection
let toRemoveForCat: string[];
toRemoveForCat = toRemove.filter((shortId)=>{
const appCats = addedCategories[shortId];
const lcCatName = levelCollections[catKey]?.name || "";
return !!appCats && appCats.map((catName: string) => catName.toUpperCase()).includes(lcCatName.toUpperCase());
})
const newAdded = collections[catKey].added.filter((appId: number) => !toRemoveForCat.map((x)=>+x).includes(appId));
collections[catKey].added = newAdded;
if(catKey.startsWith('srm') && newAdded.length == 0) {
delete collections[catKey]
// only remove the level collection if newAdded is empty *and* the level collection itself is empty
if(levelCollections[catKey] && levelCollections[catKey].added.length==0) {
cats.remove(catKey);
}
}
}
//Get the ones in levelCollection that we missed
for (const catKey of Object.keys(levelCollections)) {
if(catKey.startsWith('srm') && !collections[catKey]) {
if(levelCollections[catKey].added.length == 0) {
cats.remove(catKey);
}
}
}
//Clean out the sharedconfig
for(const sharedConfigId in sharedConfigApps) {
if(toRemove.includes(sharedConfigId) && sharedConfigApps[sharedConfigId]) {
const sharedConfigCats = Object.values(sharedConfigApps[sharedConfigId].tags||{})
const appCats = addedCategories[sharedConfigId];
const sharedConfigCatsWithoutAdded = appCats ? sharedConfigCats.filter((scCatName: string)=> {
return !(appCats.map((catName: string) => catName.toUpperCase()).includes(scCatName.toUpperCase()))
}) : sharedConfigCats;
const formattedAsTags = Object.fromEntries(sharedConfigCatsWithoutAdded.map((catName: string, i: number)=> {
return [i.toString(), catName]
}))
if(sharedConfigCatsWithoutAdded.length) {
sharedConfigApps[sharedConfigId].tags = formattedAsTags;
} else {
delete sharedConfigApps[sharedConfigId];
}
}
}

// Clean out categories
const shortIds = appIds.map((x)=> steam.shortenAppId(x));
const toRemove = _.intersection(Object.keys(addedCategories), _.union(shortIds, extraneousShortIds));
this.removeShortsFromCats(toRemove, collections, levelCollections, cats, sharedConfigApps, addedCategories);
//Add to local collections
const addableAppIds = appIds.filter((appId: string) => userData.apps[appId].status=='add');
for (let appId of addableAppIds) {
Expand Down
26 changes: 18 additions & 8 deletions src/lib/vdf-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { VDF_ListData,
VDF_ExtraneousItemsData,
VDF_AddedCategoriesData,
VDF_ScreenshotsOutcome,
VDF_AllScreenshotsOutcomes
VDF_AllScreenshotsOutcomes,
VDF_AddedItemsData
} from "../models";
import { artworkTypes, artworkIdDict } from './artwork-types';
import { superTypes, ArtworkOnlyType } from './parsers/available-parsers';
Expand Down Expand Up @@ -183,7 +184,7 @@ export class VDF_Manager {
});
}

forEach(callback: (steamDirectory: string, userId: string, listItem: VDF_ListItem) => void) {
private forEach(callback: (steamDirectory: string, userId: string, listItem: VDF_ListItem) => void) {
for (let steamDirectory in this.data) {
for (let userId in this.data[steamDirectory]) {
callback(steamDirectory, userId, this.data[steamDirectory][userId]);
Expand Down Expand Up @@ -219,16 +220,18 @@ export class VDF_Manager {
if(!deleteDisabledShortcuts) {
addedAppIds = addedAppIds.filter((appid:string) => enabledParsers.includes(addedApps[appid].parserId));
}
if(!addedCategories[steamDirectory]) {
addedCategories[steamDirectory] = {}
}
addedCategories[steamDirectory][userId] = Object.fromEntries(addedAppIds.map(appId => [steam.shortenAppId(appId), addedApps[appId].categories]))

if(!extraneousAppIds[steamDirectory]) {
extraneousAppIds[steamDirectory] = {}
}
extraneousAppIds[steamDirectory][userId] = addedAppIds.filter((appid:string) => !currentAppIds.includes(appid));
listItem.screenshots.extraneous = extraneousAppIds[steamDirectory][userId];
listItem.shortcuts.extraneous = extraneousAppIds[steamDirectory][userId];
if(!addedCategories[steamDirectory]) {
addedCategories[steamDirectory] = {}
}
addedCategories[steamDirectory][userId] = Object.fromEntries(addedAppIds.map(appId => [steam.shortenAppId(appId), addedApps[appId].categories]))

for (let appId in apps) {
let app = apps[appId];
if (app.status === 'add') {
Expand Down Expand Up @@ -307,11 +310,18 @@ export class VDF_Manager {
}

removeAllAddedEntries() {
return new Promise<{extraneousAppIds: VDF_ExtraneousItemsData,addedCategories: VDF_AddedCategoriesData}>((resolve,reject)=>{
return new Promise<{extraneousAppIds: VDF_ExtraneousItemsData, addedCategories: VDF_AddedCategoriesData}>((resolve,reject)=>{
Promise.resolve().then(()=>{
let extraneousAppIds: VDF_ExtraneousItemsData = {}
let addedCategories: VDF_AddedCategoriesData = {};
this.forEach((steamDirectory, userId, listItem) => {
const addedApps = listItem.addedItems.data.addedApps;
let addedAppIds = Object.keys(addedApps);
if(!addedCategories[steamDirectory]) {
addedCategories[steamDirectory] = {}
}
addedCategories[steamDirectory][userId] = Object.fromEntries(addedAppIds.map(appId => [steam.shortenAppId(appId), addedApps[appId].categories]))
console.log("addedCategories", addedCategories)
if(!extraneousAppIds[steamDirectory]) {
extraneousAppIds[steamDirectory] = {}
}
Expand All @@ -328,7 +338,7 @@ export class VDF_Manager {
}
listItem.addedItems.clear();
});
resolve({extraneousAppIds: extraneousAppIds, addedCategories: undefined});
resolve({extraneousAppIds: extraneousAppIds, addedCategories: addedCategories});
}).catch((error: Error) => {
reject(new VDF_Error(this.lang.error.couldNotRemoveEntries__i.interpolate({ error })));
});
Expand Down
18 changes: 2 additions & 16 deletions src/renderer/components/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,12 @@ export class SettingsComponent implements OnDestroy {
removeApps() {
if (this.knownSteamDirectories.length > 0) {
return this.previewService.saveData({removeAll: true, batchWrite: false})
.then(() => {
this.removeCategoriesOnly();
})
.then(() => {
this.removeControllersOnly();
.then(async () => {
await this.removeControllersOnly();
});
}
}

async removeCategoriesOnly() {
await steam.performSteamlessTask(this.settingsService.getSettings(), this.loggerService, async () => {
for(let steamDir of this.knownSteamDirectories) {
const accounts = await steam.getAvailableLogins(steamDir);
for(let account of accounts) {
await this.previewService.removeCategories(steamDir, account.accountID)
}
}
})
}

async removeControllersOnly() {
for(let steamDir of this.knownSteamDirectories) {
const accounts = await steam.getAvailableLogins(steamDir);
Expand Down
17 changes: 14 additions & 3 deletions src/renderer/services/preview.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,17 @@ export class PreviewService {
}


async removeCategories(steamDir: string, userId: string) {
async removeCategories(steamDir: string, userId: string, addedCategories: VDF_AddedCategoriesData[string][string]) {
try {
this.loggerService.info(`Removing category information for user ${userId}.`);
await this.categoryManager.removeAllCategoriesAndWrite(steamDir, userId);
await this.categoryManager.removeAllCategoriesAndWrite(steamDir, userId, addedCategories);
} catch(error) {
this.loggerService.error(this.lang.errors.categorySaveError, { invokeAlert: true, alertTimeout: 3000 });
this.loggerService.error(this.lang.errors.categorySaveError__i.interpolate({error:error.message}));
}
}

saveData({batchWrite, removeAll}: {batchWrite: boolean, removeAll: boolean}): Promise<any> {
saveData({batchWrite, removeAll}: {batchWrite: boolean, removeAll: boolean}): Promise<boolean> {

let knownSteamDirectories = this.parsersService.getKnownSteamDirectories();
if (this.previewVariables.listIsBeingSaved) {
Expand Down Expand Up @@ -235,6 +235,17 @@ export class PreviewService {
await this.categoryManager.save(this.previewData, exAppIds, addedCats)
})
}
if(removeAll && !this.appSettings.previewSettings.disableCategories) {
await steam.performSteamlessTask(this.appSettings, this.loggerService, async () => {
for(let steamDir of knownSteamDirectories) {
const accounts = await steam.getAvailableLogins(steamDir);
for(let account of accounts) {
console.log("addedCats", account.accountID, addedCats[steamDir][account.accountID])
await this.removeCategories(steamDir, account.accountID, addedCats[steamDir][account.accountID])
}
}
})
}
}).catch((error: Acceptable_Error | Error) => {
if(error instanceof Acceptable_Error) {
this.loggerService.error(this.lang.errors.categorySaveError, { invokeAlert: true, alertTimeout: 3000 });
Expand Down

0 comments on commit 54454f6

Please sign in to comment.