Skip to content

Commit b846867

Browse files
committed
New thunderstore UI
1 parent ca35974 commit b846867

30 files changed

+969
-326
lines changed

.node-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
14.20.1

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"build-osx": "quasar build --mode electron -T mac",
1616
"publish": "quasar build --mode electron --publish always",
1717
"publish-win": "quasar build --mode electron -T win32 --publish always",
18-
"publish-linux": "quasar build --mode electron -T linux --publish always",
18+
"publish-linux": "quasar build --mode electron -T linux --publish always",
1919
"test:unit": "jest --updateSnapshot",
2020
"test:unit:ci": "jest --ci",
2121
"test:unit:coverage": "jest --coverage",
@@ -72,8 +72,10 @@
7272
"@types/adm-zip": "^0.4.34",
7373
"@types/async-lock": "^1.1.2",
7474
"@types/chai": "^4.2.11",
75+
"@types/electron": "^1.6.10",
7576
"@types/fs-extra": "^8.0.1",
7677
"@types/lodash.debounce": "^4.0.7",
78+
"@types/mocha": "^10.0.7",
7779
"@types/node": "^12.12.12",
7880
"@types/quill": "^2.0.3",
7981
"@types/sinon": "^10.0.2",
@@ -88,7 +90,7 @@
8890
"babel-jest": "^27.0.2",
8991
"chai": "^4.2.0",
9092
"devtron": "^1.4.0",
91-
"electron": "^11.1.1",
93+
"electron": "11.5.0",
9294
"electron-builder": "22.10.5",
9395
"electron-debug": "^3.0.1",
9496
"electron-devtools-installer": "^3.0.0",
@@ -126,5 +128,6 @@
126128
"node": ">= 10.18.1",
127129
"npm": ">= 6.13.4",
128130
"yarn": ">= 1.21.1"
129-
}
131+
},
132+
"packageManager": "[email protected]"
130133
}

src-electron/main-process/electron-main.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ function createWindow() {
3939
mainWindow = new BrowserWindow({
4040
width: windowSize.width,
4141
height: windowSize.height,
42+
minWidth: 1200,
43+
minHeight: 700,
4244
useContentSize: true,
4345
webPreferences: {
4446
nodeIntegration: true,
@@ -47,7 +49,8 @@ function createWindow() {
4749
contextIsolation: false,
4850
},
4951
icon: path.join(__dirname, 'icon.png'),
50-
autoHideMenuBar: process.env.PROD
52+
autoHideMenuBar: process.env.PROD,
53+
frame: false
5154
});
5255

5356
if (windowSize.maximized) {

src-electron/main-process/ipcListeners.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ ipcMain.on('get-appData-directory', ()=>{
3434
browserWindow.webContents.send('receive-appData-directory', app.getPath('appData'));
3535
});
3636

37+
ipcMain.on('window-minimize', () => {
38+
browserWindow.minimize();
39+
})
40+
ipcMain.on('window-maximize', () => {
41+
if(browserWindow.isMaximized())
42+
browserWindow.unmaximize();
43+
else
44+
browserWindow.maximize();
45+
})
46+
ipcMain.on('window-close', () => {
47+
browserWindow.close();
48+
})
49+
3750
ipcMain.on('get-is-portable', ()=>{
3851
let isPortable = false;
3952
switch(process.platform){
@@ -68,4 +81,3 @@ ipcMain.on('show-open-dialog', (arg, fileOpts) => {
6881
browserWindow.webContents.send('receive-open-dialog', r);
6982
});
7083
});
71-

src/App.vue

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
<template>
22
<div>
3+
<div class="titlebar">
4+
<div class="titlebar_start">
5+
<p class="titlebar_title">{{ appName }}</p>
6+
<p class="titlebar_version">{{ appVersion }}</p>
7+
</div>
8+
<div class="titlebar_buttons">
9+
<div class="btn" @click="() => ipcRenderer.send('window-minimize')">
10+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.47 8.47">
11+
<path
12+
d="M 0.71464503,4.235 H 7.7550979" stroke="currentColor" fill="currentColor" stroke-linecap="round" stroke-width="1.59"/>
13+
</svg>
14+
</div>
15+
<div class="btn" @click="() => ipcRenderer.send('window-maximize')">
16+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.47 8.47">
17+
<path
18+
d="M 0.70215499,0.70215499 H 7.767847 V 7.7678511 H 0.70215499 Z" stroke="currentColor" fill="none" stroke-linecap="round" stroke-width="1.59" />
19+
</svg>
20+
</div>
21+
<div class="closebutton btn" @click="() => ipcRenderer.send('window-close')">
22+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.47 8.47">
23+
<path d="m7.67.794-6.88 6.88m0-6.88 6.88 6.88" stroke="currentColor" fill="currentColor" stroke-linecap="round" stroke-width="1.59" />
24+
</svg>
25+
</div>
26+
</div>
27+
</div>
328
<router-view v-if="visible"/>
429
<ErrorModal />
530
</div>
@@ -53,7 +78,8 @@ import ErrorModal from './components/modals/ErrorModal.vue';
5378
}
5479
})
5580
export default class App extends mixins(UtilityMixin) {
56-
private visible: boolean = false;
81+
public visible: boolean = false;
82+
readonly ipcRenderer = ipcRenderer;
5783
5884
async created() {
5985
// Load settings using the default game before the actual game is selected.
@@ -123,5 +149,13 @@ export default class App extends mixins(UtilityMixin) {
123149
BindLoaderImpl.bind();
124150
}
125151
152+
get appName(): string {
153+
return ManagerInformation.APP_NAME;
154+
}
155+
156+
get appVersion(): string {
157+
return ManagerInformation.VERSION.toString();
158+
}
159+
126160
}
127161
</script>

src/components/buttons/DonateButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<Link :url="mod.getDonationLink()"
2+
<Link :url="mod?.getDonationLink()"
33
:target="'external'"
44
class="card-footer-item"
55
v-tooltip.left="{content: 'Donate to the mod author', distance: 0}">

src/components/config-components/ConfigEditLayout.vue

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
hero-type="is-info"
77
/>
88
<br/>
9-
<div class="sticky-top sticky-top--buttons margin-right">
10-
<button class="button is-info margin-right margin-right--half-width" @click="save">Save</button>
9+
<div class="sticky-top sticky-top--buttons page-padding">
10+
<button class="button is-info margin-right--half-width" @click="save">Save</button>
1111
<button class="button is-danger" @click="cancel">Cancel</button>
1212
</div>
13-
<div v-if="configFile.getPath().toLowerCase().endsWith('.cfg')" class="margin-right non-selectable">
14-
<h3 class='subtitle is-3'>Sections</h3>
15-
<ul>
13+
<div v-if="configFile.getPath().toLowerCase().endsWith('.cfg')" class="non-selectable">
14+
<h3 class='subtitle is-3 page-padding'>Sections</h3>
15+
<ul class="page-padding">
1616
<li v-for="(value, key) in dumpedConfigVariables" :key="`${key}-${value.toString()}-tab`">
1717
<a :href="`#${key}`">{{ key }}</a>
1818
</li>
@@ -42,7 +42,7 @@
4242
<input
4343
type="range"
4444
class="slider is-fullwidth is-circle is-small"
45-
v-on:input="e => setConfigLineValue(line, e.target.value)"
45+
@input="setConfigLineValue(line, $event.target.value)"
4646
:value="parseFloat(line.value)"
4747
:min="line.getMinRange()"
4848
:max="line.getMaxRange()" />
@@ -83,11 +83,11 @@ import BepInExConfigUtils from '../../utils/BepInExConfigUtils';
8383
export default class ConfigEditLayout extends Vue {
8484
8585
@Prop({required: true})
86-
private configFile!: ConfigFile;
86+
readonly configFile!: ConfigFile;
8787
88-
private fileText: string = "";
88+
fileText: string = "";
8989
90-
private dumpedConfigVariables: { [section: string]: { [variable: string]: ConfigLine } } = {};
90+
dumpedConfigVariables: { [section: string]: { [variable: string]: ConfigLine } } = {};
9191
9292
async created() {
9393
const fs = FsProvider.instance;
@@ -150,15 +150,15 @@ import BepInExConfigUtils from '../../utils/BepInExConfigUtils';
150150
.trim();
151151
}
152152
153-
toggleEntryExpansion(key: string, variable: string) {
153+
toggleEntryExpansion(key: string | number, variable: string | number) {
154154
const oldLine = this.dumpedConfigVariables[key][variable];
155155
const newLine = new ConfigLine(oldLine.value, oldLine.comments, oldLine.allowedValues);
156156
newLine.commentsExpanded = !oldLine.commentsExpanded;
157157
this.dumpedConfigVariables[key][variable] = newLine;
158158
this.dumpedConfigVariables = JSON.parse(JSON.stringify(this.dumpedConfigVariables));
159159
}
160160
161-
setConfigLineValue(line: ConfigLine, value: number) {
161+
setConfigLineValue(line: ConfigLine, value: number | string) {
162162
line.value = value.toString();
163163
}
164164

src/components/config-components/ConfigSelectionLayout.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
</p>
1313
</div>
1414
</div>
15-
<div class='is-shadowless'>
15+
<div class='is-shadowless page-padding'>
1616
<div class='no-padding-left card-header-title'>
1717

18-
<div class="input-group input-group--flex margin-right">
18+
<div class="input-group input-group--flex">
1919
<label for="local-search" class="non-selectable">Search</label>
2020
<input id="local-search" v-model='filterText' class="input margin-right" type="text" placeholder="Search for config files"/>
2121
</div>
2222

23-
<div class="input-group margin-right">
23+
<div class="input-group">
2424
<label for="config-sort-order" class="non-selectable">Sort</label>
2525
<select id="config-sort-order" class="select select--content-spacing margin-right margin-right--half-width" v-model="sortOrder">
2626
<option v-for="(key, index) in getSortOrderOptions()" :key="`${index}-deprecated-position-option`">
@@ -36,7 +36,7 @@
3636

3737
</div>
3838
</div>
39-
<div class="margin-right">
39+
<div>
4040
<div v-for="(file, index) in sortedConfigFiles" :key="`config-file-${file.getName()}`">
4141
<ExpandableCard
4242
:id="index"
@@ -80,9 +80,9 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
8080
private configFiles: ConfigFile[] = [];
8181
private shownConfigFiles: ConfigFile[] = [];
8282
83-
private filterText: string = '';
84-
private sortOrder: SortConfigFile = SortConfigFile.NAME;
85-
private sortDirection: SortDirection = SortDirection.STANDARD;
83+
filterText: string = '';
84+
sortOrder: SortConfigFile = SortConfigFile.NAME;
85+
sortDirection: SortDirection = SortDirection.STANDARD;
8686
8787
@Watch('filterText')
8888
textChanged() {

src/components/importing/LocalFileImportModal.vue

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,20 @@ import LocalModInstallerProvider from '../../providers/ror2/installing/LocalModI
8282
export default class LocalFileImportModal extends Vue {
8383
8484
@Prop({default: false, type: Boolean})
85-
private visible!: boolean;
85+
visible!: boolean;
8686
87-
private fileToImport: string | null = null;
88-
private waitingForSelection: boolean = false;
89-
private validationMessage: string | null = null;
87+
fileToImport: string | null = null;
88+
waitingForSelection: boolean = false;
89+
validationMessage: string | null = null;
9090
91-
private modName = "";
92-
private modAuthor = "Unknown";
93-
private modDescription = "";
94-
private modVersionMajor = 0;
95-
private modVersionMinor = 0;
96-
private modVersionPatch = 0;
91+
modName = "";
92+
modAuthor = "Unknown";
93+
modDescription = "";
94+
modVersionMajor = 0;
95+
modVersionMinor = 0;
96+
modVersionPatch = 0;
9797
98-
private resultingManifest = new ManifestV2();
98+
resultingManifest = new ManifestV2();
9999
100100
@Watch("visible")
101101
private visiblityChanged() {
@@ -104,7 +104,7 @@ export default class LocalFileImportModal extends Vue {
104104
this.validationMessage = null;
105105
}
106106
107-
private async selectFile() {
107+
async selectFile() {
108108
this.waitingForSelection = true;
109109
InteractionProvider.instance.selectFile({
110110
buttonLabel: "Select file",
@@ -121,7 +121,7 @@ export default class LocalFileImportModal extends Vue {
121121
})
122122
}
123123
124-
private async assumeDefaults() {
124+
async assumeDefaults() {
125125
126126
this.modName = "";
127127
this.modAuthor = "Unknown";
@@ -180,7 +180,7 @@ export default class LocalFileImportModal extends Vue {
180180
this.modVersionPatch = inferred.modVersionPatch;
181181
}
182182
183-
private inferFieldValuesFromFile(file: string): ImportFieldAttributes {
183+
inferFieldValuesFromFile(file: string): ImportFieldAttributes {
184184
const fileSafe = file.split("\\").join("/");
185185
const fileName = path.basename(fileSafe, path.extname(fileSafe));
186186
const hyphenSeparated = fileName.split("-");
@@ -227,23 +227,23 @@ export default class LocalFileImportModal extends Vue {
227227
return data;
228228
}
229229
230-
private santizeVersionNumber(vn: string): VersionNumber {
230+
santizeVersionNumber(vn: string): VersionNumber {
231231
const modVersionSplit = vn.split(".");
232232
const modVersionString = `${this.versionPartToNumber(modVersionSplit[0])}.${this.versionPartToNumber(modVersionSplit[1])}.${this.versionPartToNumber(modVersionSplit[2])}`;
233233
return new VersionNumber(modVersionString);
234234
}
235235
236-
private versionPartToNumber(input: string | undefined) {
236+
versionPartToNumber(input: string | undefined) {
237237
return (input || "0").split(new RegExp("[^0-9]+"))
238238
.filter(value => value.trim().length > 0)
239239
.shift() || "0";
240240
}
241241
242-
private emitClose() {
242+
emitClose() {
243243
this.$emit("close-modal");
244244
}
245245
246-
private importFile() {
246+
importFile() {
247247
if (this.fileToImport === null) {
248248
return;
249249
}

src/components/modals/CategorySelectorModal.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ import { Component, Prop, Vue } from 'vue-property-decorator';
3636
export default class ChangeSelectorModal extends Vue {
3737
3838
@Prop({required: true})
39-
private title!: string;
39+
readonly title!: string;
4040
4141
@Prop({required: true})
42-
private selectedCategories!: string[]
42+
readonly selectedCategories!: string[]
4343
4444
@Prop({required: true})
45-
private selectableCategories!: string[]
45+
readonly selectableCategories!: string[]
4646
4747
emitSelected(event: Event) {
4848
this.$emit("selected-category", event);

0 commit comments

Comments
 (0)