diff options
-rw-r--r-- | src-vue/src/components/ModsMenu.vue | 25 | ||||
-rw-r--r-- | src-vue/src/utils/thunderstore/version.ts | 33 | ||||
-rw-r--r-- | src-vue/src/views/ModsView.vue | 4 | ||||
-rw-r--r-- | src-vue/src/views/mods/ThunderstoreModsView.vue | 15 |
4 files changed, 75 insertions, 2 deletions
diff --git a/src-vue/src/components/ModsMenu.vue b/src-vue/src/components/ModsMenu.vue index 03eea787..66ecc71a 100644 --- a/src-vue/src/components/ModsMenu.vue +++ b/src-vue/src/components/ModsMenu.vue @@ -9,7 +9,15 @@ <el-icon><Folder /></el-icon> <span>{{ $t('mods.menu.local') }}</span> </el-menu-item> - <el-menu-item index="2" @click="$emit('showLocalMods', false)"> + + <!-- Display a badge if there are some outdated Thunderstore mods --> + <el-menu-item v-if="outdatedThunderstoreModsCount !== 0" index="2" @click="$emit('showLocalMods', false)"> + <el-badge :value="outdatedThunderstoreModsCount" class="item" type="warning"> + <el-icon><Connection /></el-icon> + <span>{{ $t('mods.menu.online') }}</span> + </el-badge> + </el-menu-item> + <el-menu-item v-else index="2" @click="$emit('showLocalMods', false)"> <el-icon><Connection /></el-icon> <span>{{ $t('mods.menu.online') }}</span> </el-menu-item> @@ -50,6 +58,8 @@ <script lang="ts"> import { defineComponent } from 'vue' import { SortOptions } from '../utils/SortOptions.d'; +import { isThunderstoreModOutdated } from "../utils/thunderstore/version"; +import { ThunderstoreMod } from "../../../src-tauri/bindings/ThunderstoreMod"; export default defineComponent({ name: 'ModsMenu', @@ -63,6 +73,11 @@ export default defineComponent({ this.$store.state.search.sortValue = this.sortValues[3].value; }, computed: { + outdatedThunderstoreModsCount(): number { + return this.$store.state.thunderstoreMods + .filter((mod: ThunderstoreMod) => isThunderstoreModOutdated(mod)) + .length; + }, sortValues(): { label: string, value: string }[] { return Object.keys(SortOptions).map((key: string) => ({ value: key, @@ -115,4 +130,12 @@ export default defineComponent({ width: 100%; margin-top: 5px; } + +/* Outdated thunderstore mods count */ +.el-badge { + width: 100%; +} +.el-badge:deep(.el-badge__content) { + top: 28px !important; +} </style> diff --git a/src-vue/src/utils/thunderstore/version.ts b/src-vue/src/utils/thunderstore/version.ts new file mode 100644 index 00000000..a111e08c --- /dev/null +++ b/src-vue/src/utils/thunderstore/version.ts @@ -0,0 +1,33 @@ +import {ThunderstoreMod} from "../../../../src-tauri/bindings/ThunderstoreMod"; +import {NorthstarMod} from "../../../../src-tauri/bindings/NorthstarMod"; +import {store} from "../../plugins/store"; + +/** + * Strips off a Thunderstore dependency string from its version + * (e.g. "taskinoz-WallrunningTitans-1.0.0" to + * "taskinoz-WallrunningTitans"). + **/ +function getThunderstoreDependencyStringPrefix(dependency: string): string { + const dependencyStringMembers = dependency.split('-'); + return `${dependencyStringMembers[0]}-${dependencyStringMembers[1]}`; +} + +function isThunderstoreModOutdated(mod: ThunderstoreMod): boolean { + // Ensure mod is up-to-date. + const tsModPrefix = getThunderstoreDependencyStringPrefix(mod.versions[0].full_name); + const matchingMods: NorthstarMod[] = store.state.installed_mods.filter((mod: NorthstarMod) => { + if (!mod.thunderstore_mod_string) return false; + return getThunderstoreDependencyStringPrefix(mod.thunderstore_mod_string!) === tsModPrefix; + }); + if (matchingMods.length !== 0) { + // There shouldn't be several mods with same dependency string, but we never know... + const matchingMod = matchingMods[0]; + // A mod is outdated if its dependency strings differs from Thunderstore dependency string + // (no need for semver check here). + // This assumes mod versions list is sorted from newest to oldest version. + return matchingMod.thunderstore_mod_string !== mod.versions[0].full_name; + } + return false; +} + +export { isThunderstoreModOutdated }; diff --git a/src-vue/src/views/ModsView.vue b/src-vue/src/views/ModsView.vue index 7c309832..a821dcda 100644 --- a/src-vue/src/views/ModsView.vue +++ b/src-vue/src/views/ModsView.vue @@ -37,6 +37,10 @@ export default defineComponent({ return { show_local_mods: true, } + }, + mounted() { + // Fetch Thunderstore mods to eventually display outdated mods count + this.$store.commit('fetchThunderstoreMods'); } }); </script> diff --git a/src-vue/src/views/mods/ThunderstoreModsView.vue b/src-vue/src/views/mods/ThunderstoreModsView.vue index 538a895f..6f5e8acf 100644 --- a/src-vue/src/views/mods/ThunderstoreModsView.vue +++ b/src-vue/src/views/mods/ThunderstoreModsView.vue @@ -52,6 +52,8 @@ import { ElScrollbar, ScrollbarInstance } from "element-plus"; import { SortOptions } from "../../utils/SortOptions.d";
import { ThunderstoreModVersion } from "../../../../src-tauri/bindings/ThunderstoreModVersion";
import { fuzzy_filter } from "../../utils/filter";
+import { isThunderstoreModOutdated } from "../../utils/thunderstore/version";
+
export default defineComponent({
name: "ThunderstoreModsView",
@@ -137,7 +139,18 @@ export default defineComponent({ throw new Error('Unknown mod sorting.');
}
- return mods.sort(compare);
+ // Always display outdated mods first
+ // (regardless of actual sort order)
+ const sortedMods = mods.sort(compare);
+ return sortedMods.sort((a, b) => {
+ if (isThunderstoreModOutdated(a)) {
+ return -1;
+ } else if (isThunderstoreModOutdated(b)) {
+ return 1;
+ } else {
+ return compare(a, b);
+ }
+ })
},
modsPerPage(): number {
return parseInt(this.$store.state.mods_per_page);
|