summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Web')
-rw-r--r--src/SMAPI.Web/Views/Mods/Index.cshtml11
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/mods.js77
2 files changed, 66 insertions, 22 deletions
diff --git a/src/SMAPI.Web/Views/Mods/Index.cshtml b/src/SMAPI.Web/Views/Mods/Index.cshtml
index 372d6706..a49a24d9 100644
--- a/src/SMAPI.Web/Views/Mods/Index.cshtml
+++ b/src/SMAPI.Web/Views/Mods/Index.cshtml
@@ -4,11 +4,11 @@
ViewData["Title"] = "SMAPI mod compatibility";
}
@section Head {
- <link rel="stylesheet" href="~/Content/css/mods.css?r=20181109" />
+ <link rel="stylesheet" href="~/Content/css/mods.css?r=20181122" />
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/tablesorter@2.31.0/dist/js/jquery.tablesorter.combined.min.js" crossorigin="anonymous"></script>
- <script src="~/Content/js/mods.js?r=20181109"></script>
+ <script src="~/Content/js/mods.js?r=20181122"></script>
<script>
$(function() {
var data = @Json.Serialize(Model.Mods, new JsonSerializerSettings { Formatting = Formatting.None });
@@ -36,7 +36,7 @@
</div>
<div id="filter-area">
<input type="checkbox" id="show-advanced" v-model="showAdvanced" />
- <label for="show-advanced">show detailed options</label>
+ <label for="show-advanced">show advanced info and options</label>
<div id="filters" v-show="showAdvanced">
<div v-for="(filterGroup, key) in filters">
{{key}}: <span v-for="filter in filterGroup" v-bind:class="{ active: filter.value }"><input type="checkbox" v-bind:id="filter.id" v-model="filter.value" v-on:change="applyFilters" /> <label v-bind:for="filter.id">{{filter.label}}</label></span>
@@ -44,7 +44,10 @@
</div>
</div>
</div>
- <div id="mod-count" v-show="showAdvanced">{{visibleCount}} mods shown.</div>
+ <div id="mod-count" v-show="showAdvanced">
+ <span v-if="visibleStats.total > 0">{{visibleStats.total}} mods shown ({{Math.round((visibleStats.compatible + visibleStats.workaround) / visibleStats.total * 100)}}% compatible or have a workaround, {{Math.round((visibleStats.soon + visibleStats.broken) / visibleStats.total * 100)}}% broken, {{Math.round(visibleStats.abandoned / visibleStats.total * 100)}}% obsolete).</span>
+ <span v-else>No matching mods found.</span>
+ </div>
<table class="wikitable" id="mod-list">
<thead>
<tr>
diff --git a/src/SMAPI.Web/wwwroot/Content/js/mods.js b/src/SMAPI.Web/wwwroot/Content/js/mods.js
index 2cff551f..b4dc6986 100644
--- a/src/SMAPI.Web/wwwroot/Content/js/mods.js
+++ b/src/SMAPI.Web/wwwroot/Content/js/mods.js
@@ -4,10 +4,19 @@ var smapi = smapi || {};
var app;
smapi.modList = function (mods) {
// init data
+ var defaultStats = {
+ total: 0,
+ compatible: 0,
+ workaround: 0,
+ soon: 0,
+ broken: 0,
+ abandoned: 0,
+ invalid: 0
+ };
var data = {
mods: mods,
- visibleCount: mods.length,
showAdvanced: false,
+ visibleStats: $.extend({}, defaultStats),
filters: {
source: {
open: {
@@ -130,27 +139,16 @@ smapi.modList = function (mods) {
var words = data.search.toLowerCase().split(" ");
// apply criteria
- data.visibleCount = data.mods.length;
+ var stats = data.visibleStats = $.extend({}, defaultStats);
for (var i = 0; i < data.mods.length; i++) {
var mod = data.mods[i];
mod.Visible = true;
// check filters
- if (!this.matchesFilters(mod)) {
- mod.Visible = false;
- data.visibleCount--;
- continue;
- }
-
- // check search terms (all search words should match)
- if (words.length) {
- for (var w = 0; w < words.length; w++) {
- if (mod.SearchableText.indexOf(words[w]) === -1) {
- mod.Visible = false;
- data.visibleCount--;
- break;
- }
- }
+ mod.Visible = this.matchesFilters(mod, words);
+ if (mod.Visible) {
+ stats.total++;
+ stats[this.getCompatibilityGroup(mod)]++;
}
}
},
@@ -159,9 +157,10 @@ smapi.modList = function (mods) {
/**
* Get whether a mod matches the current filters.
* @param {object} mod The mod to check.
+ * @param {string[]} searchWords The search words to match.
* @returns {bool} Whether the mod matches the filters.
*/
- matchesFilters: function(mod) {
+ matchesFilters: function(mod, searchWords) {
var filters = data.filters;
// check source
@@ -198,8 +197,50 @@ smapi.modList = function (mods) {
return false;
}
+ // check search terms
+ for (var w = 0; w < searchWords.length; w++) {
+ if (mod.SearchableText.indexOf(searchWords[w]) === -1)
+ return false;
+ }
+
return true;
+ },
+
+ /**
+ * Get a mod's compatibility group for mod metrics.
+ * @param {object} mod The mod to check.
+ * @returns {string} The compatibility group (one of 'compatible', 'workaround', 'soon', 'broken', 'abandoned', or 'invalid').
+ */
+ getCompatibilityGroup: function (mod) {
+ var status = (mod.BetaCompatibility || mod.Compatibility).Status;
+ switch (status) {
+ // obsolete
+ case "abandoned":
+ case "obsolete":
+ return "abandoned";
+
+ // compatible
+ case "ok":
+ case "optional":
+ return "compatible";
+
+ // workaround
+ case "workaround":
+ case "unofficial":
+ return "workaround";
+
+ // soon/broken
+ case "broken":
+ if (mod.SourceUrl)
+ return "soon";
+ else
+ return "broken";
+
+ default:
+ return "invalid";
+ }
}
}
});
+ app.applyFilters();
};