-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/composables/useSettings.ts b/composables/useSettings.ts
new file mode 100644
index 0000000..c974b9f
--- /dev/null
+++ b/composables/useSettings.ts
@@ -0,0 +1,16 @@
+export type Version = "major" | "minor" | "all"
+
+export function useSettings() {
+ let version = useCookie
("version", {
+ maxAge: 60 * 60 * 24 * 30, sameSite: true, default: () => {
+ return "major";
+ },
+ });
+ let exclusive = useCookie("exclusive", {
+ maxAge: 60 * 60 * 24 * 30, sameSite: true, default: () => {
+ return false;
+ },
+ });
+
+ return {version, exclusive}
+}
\ No newline at end of file
diff --git a/composables/useVersion.ts b/composables/useVersion.ts
deleted file mode 100644
index cd8523c..0000000
--- a/composables/useVersion.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export type Version = "major" | "minor" | "all"
-
-export function useVersion() {
- let cookie = useCookie("version", {maxAge: 60 * 60 * 24 * 30, sameSite: true});
-
- if (!cookie.value) {
- cookie.value = "major"
- }
-
- return cookie
-}
\ No newline at end of file
diff --git a/pages/[type]/downloads.vue b/pages/[type]/downloads.vue
index 1245e7e..5b81af3 100644
--- a/pages/[type]/downloads.vue
+++ b/pages/[type]/downloads.vue
@@ -6,8 +6,6 @@ useHead({
title: `Number of downloads of ${route.params.type}`
})
-const version = useVersion();
-
const explanation = `
Number of Downloads per Specific Loader/Game-Version
diff --git a/server/api/stats.ts b/server/api/stats.ts
index c197ccf..536e073 100644
--- a/server/api/stats.ts
+++ b/server/api/stats.ts
@@ -6,10 +6,11 @@ export default defineEventHandler(async (event): Promise => {
let mode = query.mode as string;
let type = query.type as ProjectTypes;
+ let exclusive = query.exclusive === "true";
if (query.stat == "versions") {
- return exportStats(mode, type, value => value.versions)
+ return exportStats(mode, type, exclusive, value => value.versions)
} else {
- return exportStats(mode, type, value => value.downloads)
+ return exportStats(mode, type, exclusive, value => value.downloads)
}
})
\ No newline at end of file
diff --git a/server/utils/api/stats.ts b/server/utils/api/stats.ts
index 0386624..7670191 100644
--- a/server/utils/api/stats.ts
+++ b/server/utils/api/stats.ts
@@ -1,5 +1,7 @@
import {Stats, StatsValue} from "~/server/utils/types/stats";
import {ProjectTypes} from "~/utils/project";
+import {firstLetterUpperCase} from "~/utils/text";
+import consola from "consola";
export type StatExport = {
labels: string[]
@@ -10,23 +12,20 @@ export type StatExport = {
}[]
}
-export async function exportStats(mode: string, type: ProjectTypes, fn: (value: StatsValue) => number): Promise {
+export async function exportStats(mode: string, type: ProjectTypes, exclusive: boolean, fn: (value: StatsValue) => number): Promise {
const storage = useStorage("statistics");
- let stats
-
- switch (mode) {
- case "minor" :
- stats = await storage.getItem(`${type}StatsMinor`)
- break
- case "all" :
- stats = await storage.getItem(`${type}StatsAll`)
- break
- default:
- stats = await storage.getItem(`${type}StatsMajor`)
+
+ let key = `${type}Stats${firstLetterUpperCase(mode)}`;
+
+ if (exclusive) {
+ key += "Exclusive"
}
+ let stats = await storage.getItem(key)
+
if (!stats) {
- // todo - error message
+ consola.error(`could not find stats for key - "${key}"`)
+
return {
labels: [],
data: []
diff --git a/server/utils/statistics.ts b/server/utils/statistics.ts
index 4a3b199..8bf96e4 100644
--- a/server/utils/statistics.ts
+++ b/server/utils/statistics.ts
@@ -3,8 +3,12 @@ import {GameVersion, Version} from "~/server/utils/fetchData";
import {projectTypeList, ProjectTypes} from "~/utils/project";
import consola from "consola";
-type StatsData = Map>
-type AllStats = { all: Stats, minor: Stats, major: Stats };
+type StatsDataEntry = Map>
+type StatsData = { all: StatsDataEntry, exclusive: StatsDataEntry }
+
+type AllStatsEntry = { all: Stats, minor: Stats, major: Stats };
+type AllStats = { all: AllStatsEntry, exclusive: AllStatsEntry }
+
export async function updateStatistics() {
for (let type of projectTypeList) {
@@ -20,15 +24,19 @@ async function updateStatistic(type: ProjectTypes) {
async function saveStats(stats: AllStats, type: ProjectTypes) {
const storage = useStorage("statistics");
- await storage.setItem(`${type}StatsAll`, stats.all)
- await storage.setItem(`${type}StatsMinor`, stats.minor)
- await storage.setItem(`${type}StatsMajor`, stats.major
- )
+
+ await storage.setItem(`${type}StatsAll`, stats.all.all)
+ await storage.setItem(`${type}StatsMinor`, stats.all.minor)
+ await storage.setItem(`${type}StatsMajor`, stats.all.major)
+
+ await storage.setItem(`${type}StatsAllExclusive`, stats.exclusive.all)
+ await storage.setItem(`${type}StatsMinorExclusive`, stats.exclusive.minor)
+ await storage.setItem(`${type}StatsMajorExclusive`, stats.exclusive.major)
}
async function getStatistics(type: ProjectTypes): Promise {
const BATCH_COUNT = import.meta.dev ? 1 : 10;
- let data: StatsData = new Map()
+ let data: StatsData = {all: new Map(), exclusive: new Map()}
let index = 0;
@@ -55,14 +63,21 @@ async function getStatistics(type: ProjectTypes): Promise {
}
let versions = await getGameVersions()
- let allDownloads = StatsFromData(versions, data);
- let {gameVersions: minorGameVersions, downloads: minorVersionDownloads} = onlyMinorVersions(versions, allDownloads);
- let majorVersionDownloads = onlyMajorVersions(minorGameVersions, minorVersionDownloads);
+
+ function toVersions(data: StatsDataEntry): AllStatsEntry {
+ let allDownloads = StatsFromData(versions, data);
+ let {
+ gameVersions: minorGameVersions,
+ downloads: minorVersionDownloads
+ } = onlyMinorVersions(versions, allDownloads);
+ let majorVersionDownloads = onlyMajorVersions(minorGameVersions, minorVersionDownloads);
+
+ return {all: allDownloads, minor: minorVersionDownloads, major: majorVersionDownloads};
+ }
return {
- all: allDownloads,
- major: majorVersionDownloads,
- minor: minorVersionDownloads
+ all: toVersions(data.all),
+ exclusive: toVersions(data.exclusive)
}
}
@@ -90,21 +105,28 @@ function analyzeVersions(versions: Version[], data: StatsData, type: ProjectType
// compensate for a version contributing to multiple loaders and versions
let versionDownloads = version.downloads / (allowedLaunchers.length * version.game_versions.length)
- for (let loader of allowedLaunchers) {
- if (!data.has(loader)) {
- data.set(loader, new Map())
- }
+ insertLauncherData(allowedLaunchers, data.all, version, versionDownloads);
+ if (allowedLaunchers.length == 1) {
+ insertLauncherData(allowedLaunchers, data.exclusive, version, versionDownloads);
+ }
+ }
+}
- let downloads = data.get(loader)!;
+function insertLauncherData(allowedLaunchers: Array, data: StatsDataEntry, version: Version, versionDownloads: number) {
+ for (let loader of allowedLaunchers) {
+ if (!data.has(loader)) {
+ data.set(loader, new Map())
+ }
+
+ let downloads = data.get(loader)!;
- for (let gameVersion of version.game_versions) {
- if (downloads.has(gameVersion)) {
- let data = downloads.get(gameVersion)!;
+ for (let gameVersion of version.game_versions) {
+ if (downloads.has(gameVersion)) {
+ let data = downloads.get(gameVersion)!;
- downloads.set(gameVersion, {downloads: data.downloads + versionDownloads, count: data.count + 1})
- } else {
- downloads.set(gameVersion, {downloads: versionDownloads, count: 1})
- }
+ downloads.set(gameVersion, {downloads: data.downloads + versionDownloads, count: data.count + 1})
+ } else {
+ downloads.set(gameVersion, {downloads: versionDownloads, count: 1})
}
}
}
@@ -186,7 +208,7 @@ function onlyMajorVersions(gameVersions: GameVersion[], all: Stats): Stats {
return downloads
}
-function StatsFromData(versions: GameVersion[], data: StatsData): Stats {
+function StatsFromData(versions: GameVersion[], data: StatsDataEntry): Stats {
const versionArray = versions.map(value => {
return value.name
})
diff --git a/utils/text.ts b/utils/text.ts
new file mode 100644
index 0000000..f0e87e0
--- /dev/null
+++ b/utils/text.ts
@@ -0,0 +1,3 @@
+export function firstLetterUpperCase(text: string): string {
+ return text.charAt(0).toUpperCase() + text.slice(1);
+}
\ No newline at end of file