Skip to content

Commit 07a3be8

Browse files
committed
New thunderstore UI
1 parent ca35974 commit 07a3be8

23 files changed

+729
-144
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: 5 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,6 +72,7 @@
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",
7778
"@types/node": "^12.12.12",
@@ -88,7 +89,7 @@
8889
"babel-jest": "^27.0.2",
8990
"chai": "^4.2.0",
9091
"devtron": "^1.4.0",
91-
"electron": "^11.1.1",
92+
"electron": "11.5.0",
9293
"electron-builder": "22.10.5",
9394
"electron-debug": "^3.0.1",
9495
"electron-devtools-installer": "^3.0.0",
@@ -126,5 +127,6 @@
126127
"node": ">= 10.18.1",
127128
"npm": ">= 6.13.4",
128129
"yarn": ">= 1.21.1"
129-
}
130+
},
131+
"packageManager": "[email protected]"
130132
}

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: 30 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">r2modman</p>
6+
<p class="titlebar_version"></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.
@@ -62,6 +88,9 @@ export default class App extends mixins(UtilityMixin) {
6288
this.hookThunderstoreModListRefresh();
6389
await this.checkCdnConnection();
6490
91+
const version_text = document.querySelector(".titlebar_version")
92+
if(version_text !== null) version_text.textContent = ManagerInformation.VERSION.toString()
93+
6594
InstallationRuleApplicator.apply();
6695
InstallationRules.validate();
6796

src/components/config-components/ConfigSelectionLayout.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
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>
Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,102 @@
11
<template>
2-
<div id="content" class="columns">
3-
<div class="column non-selectable is-one-quarter">
4-
<NavigationMenu />
5-
</div>
6-
<div class="column">
7-
<router-view />
2+
<div id="content" class="dashboard">
3+
<NavigationMenu />
4+
<div class="">
5+
<div class="top-bar">
6+
<div
7+
class="profile"
8+
@click="$router.push({ name: 'profiles' })"
9+
>
10+
{{ activeProfile.profileName }}
11+
<p>Change profile</p>
12+
</div>
13+
<div class="play-buttons">
14+
<button class="vanilla" @click="launch(LaunchMode.VANILLA)">
15+
<i class="far fa-play-circle icon--margin-right"/>Vanilla
16+
</button>
17+
<button class="modded" @click="launch(LaunchMode.MODDED)">
18+
<i class="fas fa-play-circle icon--margin-right"/>Modded
19+
</button>
20+
</div>
21+
</div>
22+
<div class="router-page">
23+
<router-view />
24+
</div>
825
</div>
926
<GameRunningModal :activeGame="$store.state.activeGame" />
1027
</div>
1128
</template>
1229

1330
<script lang="ts">
14-
1531
import { Component, Vue } from 'vue-property-decorator';
1632
1733
import NavigationMenu from './NavigationMenu.vue';
1834
import GameRunningModal from '../modals/GameRunningModal.vue';
35+
import {
36+
LaunchMode,
37+
launch,
38+
linkProfileFiles,
39+
setGameDirIfUnset,
40+
throwIfNoGameDir
41+
} from '../../utils/LaunchUtils';
42+
43+
import R2Error from '../../model/errors/R2Error';
44+
import Game from '../../model/game/Game';
45+
import Profile from '../../model/Profile';
46+
import ManagerSettings from '../../r2mm/manager/ManagerSettings';
1947
2048
@Component({
21-
components: {GameRunningModal, NavigationMenu}
49+
components: { GameRunningModal, NavigationMenu },
2250
})
23-
export default class NavigationLayout extends Vue {}
51+
export default class NavigationLayout extends Vue {
52+
readonly LaunchMode = LaunchMode;
53+
54+
get activeProfile() {
55+
return this.$store.state.profile.activeProfile;
56+
}
57+
get activeGame(): Game {
58+
return this.$store.state.activeGame;
59+
}
60+
61+
async changeGame() {
62+
await ManagerSettings.resetDefaults();
63+
await this.$router.push({name: 'index'});
64+
}
65+
66+
get profile(): Profile {
67+
return this.$store.getters['profile/activeProfile'];
68+
};
69+
70+
get thunderstoreModCount() {
71+
return this.$store.state.modFilters.showDeprecatedPackages
72+
? this.$store.state.tsMods.mods.length
73+
: this.$store.getters['tsMods/undeprecatedModCount'];
74+
}
75+
76+
get localModCount(): number {
77+
return this.$store.state.profile.modList.length;
78+
}
79+
80+
getTagLinkClasses(routeNames: string[]) {
81+
const base = ["tag", "tagged-link__tag"];
82+
return routeNames.includes(this.$route.name || "") ? base : [...base, "is-link"];
83+
}
84+
85+
async launch(mode: LaunchMode) {
86+
try {
87+
await setGameDirIfUnset(this.activeGame);
88+
await throwIfNoGameDir(this.activeGame);
89+
90+
if (mode === LaunchMode.MODDED) {
91+
await linkProfileFiles(this.activeGame, this.profile);
92+
}
2493
94+
this.$store.commit("openGameRunningModal");
95+
await launch(this.activeGame, this.profile, mode);
96+
} catch (error) {
97+
this.$store.commit("closeGameRunningModal");
98+
this.$store.commit("error/handleError", R2Error.fromThrownValue(error));
99+
}
100+
}
101+
}
25102
</script>

0 commit comments

Comments
 (0)