summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web/Views/Mods/Index.cshtml
blob: 4b6400ad0c4b3dfa0349783c6b6f5dd09b9bc908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@{
    #nullable disable
}

@using Humanizer
@using Humanizer.Localisation
@using StardewModdingAPI.Web.Framework
@using StardewModdingAPI.Web.ViewModels
@model StardewModdingAPI.Web.ViewModels.ModListModel
@{
    ViewData["Title"] = "Mod compatibility";

    TimeSpan staleAge = DateTimeOffset.UtcNow - Model.LastUpdated;

    bool hasBeta = Model.BetaVersion != null;
    string betaLabel = $"SDV {Model.BetaVersion} only";
}
@section Head {
    <link rel="stylesheet" href="~/Content/css/mods.css?r=20200218" />
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/tablesorter@2.31.3" crossorigin="anonymous"></script>
    <script src="~/Content/js/mods.js?r=20210929"></script>
    <script>
        $(function() {
            var data = @(this.ForJson(Model.Mods ?? Array.Empty<ModModel>()));
            var enableBeta = @this.ForJson(hasBeta);
            smapi.modList(data, enableBeta);
        });
    </script>
}

@if (!Model.HasData)
{
    <div class="error">↻ The mod data hasn't been fetched yet; please try again in a few minutes.</div>
}
else
{
    @if (Model.IsStale)
    {
        <div class="error">Showing data from @staleAge.Humanize(maxUnit: TimeUnit.Hour, minUnit: TimeUnit.Minute) ago. (Couldn't fetch newer data; the wiki API may be offline.)</div>
    }

    <div id="app">
        <div id="intro">
            <p>This page shows all known SMAPI mods and (incompatible) content packs, whether they work with the latest versions of Stardew Valley and SMAPI, and how to fix them if not. If a mod doesn't work after following the instructions below, check <a href="https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting">the troubleshooting guide</a> or <a href="https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#Ask_for_help">ask for help</a>.</p>

            <p>The list is updated every few days (you can help <a href="https://stardewvalleywiki.com/Modding:Mod_compatibility">update it</a>!). It doesn't include XNB mods (see <a href="https://stardewvalleywiki.com/Modding:Using_XNB_mods"><em>using XNB mods</em> on the wiki</a> instead) or compatible content packs.</p>

            @if (hasBeta)
            {
                <p id="beta-blurb"><strong>Note:</strong> "@betaLabel" lines are for the beta version of Stardew Valley, not the stable version most players have. If a mod doesn't have that line, the info applies to both versions.</p>
            }
        </div>

        <div id="options">
            <div>
                <label for="search-box">Search: </label>
                <input type="text" id="search-box" v-model="search" v-on:input="applyFilters" />
            </div>
            <div id="filter-area">
                <input type="checkbox" id="show-advanced" v-model="showAdvanced" />
                <label for="show-advanced">show advanced info and options</label>
                <div id="filters" v-show="showAdvanced">
                    <div v-for="(filterGroup, key) in filters">
                        {{filterGroup.label}}: <span v-for="filter in filterGroup.value" 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>
                    </div>
                </div>
            </div>
        </div>
        <div id="mod-count" v-show="showAdvanced">
            <div v-if="visibleMainStats.total > 0">
                {{visibleMainStats.total}} mods shown ({{visibleMainStats.percentCompatible}}% compatible or have a workaround, {{visibleMainStats.percentBroken}}% broken, {{visibleMainStats.percentObsolete}}% obsolete).
            </div>
            @if (hasBeta)
            {
                <div v-if="visibleBetaStats.total > 0">
                    <strong>@betaLabel</strong>: {{visibleBetaStats.total}} mods shown ({{visibleBetaStats.percentCompatible}}% compatible or have a workaround, {{visibleBetaStats.percentBroken}}% broken, {{visibleBetaStats.percentObsolete}}% obsolete).
                </div>
            }
            <span v-else>No matching mods found.</span>
        </div>
        <table class="wikitable" id="mod-list">
            <thead>
                <tr>
                    <th>mod name</th>
                    <th>links</th>
                    <th>author</th>
                    <th>compatibility</th>
                    <th v-show="showAdvanced">broke in</th>
                    <th v-show="showAdvanced">code</th>
                    <th>&nbsp;</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="mod in mods" :key="mod.Slug" v-bind:id="mod.Slug" v-bind:data-status="mod.Compatibility.Status" v-show="mod.Visible">
                    <td>
                        {{mod.Name}}
                        <small class="mod-alt-names" v-if="mod.AlternateNames">(aka {{mod.AlternateNames}})</small>
                    </td>
                    <td class="mod-page-links">
                        <span v-for="(link, i) in mod.ModPages">
                            <a v-bind:href="link.Url">{{link.Text}}</a>{{i &lt; mod.ModPages.length - 1 ? ', ' : ''}}
                        </span>
                    </td>
                    <td>
                        {{mod.Author}}
                        <small class="mod-alt-authors" v-if="mod.AlternateAuthors">(aka {{mod.AlternateAuthors}})</small>
                    </td>
                    <td>
                        <div v-html="mod.Compatibility.Summary"></div>
                        <div v-if="mod.BetaCompatibility">
                            <strong v-if="mod.BetaCompatibility">@betaLabel:</strong>
                            <span v-html="mod.BetaCompatibility.Summary"></span>
                        </div>
                        <div v-for="(warning, i) in mod.Warnings">⚠ {{warning}}</div>
                    </td>
                    <td class="mod-broke-in" v-html="mod.LatestCompatibility.BrokeIn" v-show="showAdvanced"></td>
                    <td v-show="showAdvanced">
                        <span v-if="mod.SourceUrl">
                            <a v-bind:href="mod.SourceUrl">source</a>
                            <span v-if="mod.GitHubRepo">
                                @* see https://shields.io/category/license *@
                                (<img v-bind:src="'https://img.shields.io/github/license/' + mod.GitHubRepo + '?style=flat-square.png&label='" class="license-badge" alt="source" />)
                            </span>
                        </span>
                        <span v-else class="mod-closed-source">no source</span>
                    </td>
                    <td>
                        <small>
                            <a v-bind:href="'#' + mod.Slug">#</a>
                            <span v-show="showAdvanced">
                                <a v-bind:href="mod.PullRequestUrl" v-if="mod.PullRequestUrl">PR</a>
                                <abbr v-bind:title="mod.DevNote" v-if="mod.DevNote">[dev note]</abbr>
                            </span>
                        </small>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
}