aboutsummaryrefslogtreecommitdiff
path: root/src-vue/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src-vue/src/components')
-rw-r--r--src-vue/src/components/ModsMenu.vue118
-rw-r--r--src-vue/src/components/ThunderstoreModCard.vue83
2 files changed, 199 insertions, 2 deletions
diff --git a/src-vue/src/components/ModsMenu.vue b/src-vue/src/components/ModsMenu.vue
new file mode 100644
index 00000000..9b62fcfa
--- /dev/null
+++ b/src-vue/src/components/ModsMenu.vue
@@ -0,0 +1,118 @@
+<template>
+ <nav class="fc_mods__menu">
+ <el-menu
+ default-active="1"
+ text-color="#fff"
+ >
+ <h5>Mods</h5>
+ <el-menu-item index="1" @click="$emit('showLocalMods', true)">
+ <el-icon><Folder /></el-icon>
+ <span>Local</span>
+ </el-menu-item>
+ <el-menu-item index="2" @click="$emit('showLocalMods', false)">
+ <el-icon><Connection /></el-icon>
+ <span>Online</span>
+ </el-menu-item>
+
+ <!-- Search inputs -->
+ <h5>Filter</h5>
+ <el-input v-model="$store.state.search.searchValue" placeholder="Search" clearable />
+ <el-select
+ v-if="!showingLocalMods"
+ v-model="$store.state.search.sortValue"
+ placeholder="Sort mods"
+ >
+ <el-option
+ v-for="item of sortValues"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
+ <el-select
+ v-if="!showingLocalMods"
+ v-model="$store.state.search.selectedCategories"
+ multiple
+ placeholder="Select categories"
+ >
+ <el-option
+ v-for="item in $store.state.thunderstoreModsCategories"
+ :key="item"
+ :label="item"
+ :value="item"
+ />
+ </el-select>
+
+ </el-menu>
+ </nav>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue'
+import { SortOptions } from '../utils/SortOptions.d';
+
+export default defineComponent({
+ name: 'ModsMenu',
+ props: {
+ showingLocalMods: {
+ required: true,
+ type: Boolean
+ }
+ },
+ mounted() {
+ this.$store.state.search.sortValue = this.sortValues[3].value;
+ },
+ computed: {
+ sortValues(): {label: string, value: string}[] {
+ return Object.keys(SortOptions).map((key: string) => ({
+ value: key,
+ label: Object.values(SortOptions)[Object.keys(SortOptions).indexOf(key)]
+ }));
+ }
+ }
+})
+</script>
+
+<style scoped>
+.fc_mods__menu {
+ display: flex;
+ max-width: 222px;
+ min-width: 222px;
+ padding: 10px;
+}
+
+.fc_mods__menu h5 {
+ margin: 8px 0 16px 5px;
+}
+
+.fc_mods__menu h5:not(:first-child){
+ margin-top: 32px;
+}
+
+.fc_mods__menu > .el-menu {
+ background-color: transparent;
+ border: none;
+ width: 100%;
+}
+
+.fc_mods__menu > .el-menu > .el-menu-item {
+ height: 32px;
+ margin-bottom: 5px;
+ border-radius: 5px;
+ color: #e2e6e7;
+}
+
+.fc_mods__menu > .el-menu > .el-menu-item:hover {
+ background-color: #4e4e4e3b;
+}
+
+.fc_mods__menu > .el-menu > .el-menu-item.is-active {
+ color: white;
+ background-color: #4e4e4e7a;
+}
+
+.el-select {
+ width: 100%;
+ margin-top: 5px;
+}
+</style>
diff --git a/src-vue/src/components/ThunderstoreModCard.vue b/src-vue/src/components/ThunderstoreModCard.vue
index 1e742fa2..a202aa50 100644
--- a/src-vue/src/components/ThunderstoreModCard.vue
+++ b/src-vue/src/components/ThunderstoreModCard.vue
@@ -35,11 +35,30 @@
>
{{ modButtonText }}
</el-button>
- <el-button link type="info" class="infoBtn" @click="openURL(mod.package_url)">
+
+ <!-- Information dropdown menu -->
+ <el-button v-if="!modIsRemovable"
+ link type="info" class="infoBtn" @click="openURL(mod.package_url)">
<el-icon>
<InfoFilled />
</el-icon>
</el-button>
+
+ <el-dropdown v-else>
+ <el-icon class="infoBtn moreBtn">
+ <MoreFilled />
+ </el-icon>
+ <template #dropdown>
+ <el-dropdown-menu>
+ <el-dropdown-item @click="openURL(mod.package_url)">
+ More info
+ </el-dropdown-item>
+ <el-dropdown-item @click="deleteMod(mod)">
+ Remove mod
+ </el-dropdown-item>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
</span>
</div>
</el-card>
@@ -54,6 +73,8 @@ import {ThunderstoreModStatus} from "../utils/thunderstore/ThunderstoreModStatus
import {NorthstarMod} from "../utils/NorthstarMod";
import {GameInstall} from "../utils/GameInstall";
import {ElNotification} from "element-plus";
+import { NorthstarState } from "../utils/NorthstarState";
+import { ElMessageBox } from "element-plus";
export default defineComponent({
name: "ThunderstoreModCard",
@@ -138,6 +159,15 @@ export default defineComponent({
},
/**
+ * Tells if a Thunderstore mod can be removed.
+ * This is used to tell if we should display the "Remove mod" option.
+ **/
+ modIsRemovable(): boolean {
+ return [ThunderstoreModStatus.INSTALLED, ThunderstoreModStatus.OUTDATED]
+ .includes(this.modStatus);
+ },
+
+ /**
* This computes the total count of downloads of a given mod, by adding
* download count of each of its releases.
*/
@@ -166,6 +196,50 @@ export default defineComponent({
return `${dependencyStringMembers[0]}-${dependencyStringMembers[1]}`;
},
+ async deleteMod(mod: ThunderstoreMod) {
+
+ // Show pop-up to confirm delete
+ ElMessageBox.confirm(
+ 'Delete Thunderstore mod?',
+ 'Warning',
+ {
+ confirmButtonText: 'OK',
+ cancelButtonText: 'Cancel',
+ type: 'warning',
+ }
+ )
+ .then(async () => { // Deletion confirmed
+ let game_install = {
+ game_path: this.$store.state.game_path,
+ install_type: this.$store.state.install_type
+ } as GameInstall;
+
+ await invoke("delete_thunderstore_mod", { gameInstall: game_install, thunderstoreModString: this.latestVersion.full_name })
+ .then((message) => {
+ ElNotification({
+ title: `Removed ${mod.name}`,
+ message: message as string,
+ type: 'success',
+ position: 'bottom-right'
+ });
+ })
+ .catch((error) => {
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ })
+ .finally(() => {
+ this.$store.commit('loadInstalledMods');
+ });
+ })
+ .catch(() => { // Deletion cancelled
+ console.log("Deleting Thunderstore mod cancelled.")
+ })
+ },
+
async installMod (mod: ThunderstoreMod) {
let game_install = {
game_path: this.$store.state.game_path,
@@ -241,8 +315,13 @@ export default defineComponent({
.infoBtn {
width: 20px;
- padding: 0;
+ padding: 0 !important;
font-size: 20px;
border: none;
}
+
+.moreBtn {
+ margin-left: 10px;
+ height: auto;
+}
</style>