Browse Source

Feat: Show Version in Footer (#1389)

update ui logic, always store release in global store.

new release logic uses rate limited github api, avoid using cache
pull/1648/head
Bernd Storath 7 months ago
committed by Bernd Storath
parent
commit
08a5f76793
  1. 1
      src/app/app.vue
  2. 6
      src/app/layouts/Footer.vue
  3. 2
      src/app/layouts/Header.vue
  4. 12
      src/app/stores/global.ts
  5. 3
      src/server/api/release.get.ts
  6. 2
      src/server/utils/config.ts
  7. 27
      src/server/utils/release.ts

1
src/app/app.vue

@ -10,6 +10,7 @@
const globalStore = useGlobalStore();
globalStore.fetchFeatures();
globalStore.fetchRelease();
globalStore.setLanguage();
useHead({
bodyAttrs: {
class: 'bg-gray-50 dark:bg-neutral-800',

6
src/app/layouts/Footer.vue

@ -7,7 +7,7 @@
href="https://github.com/wg-easy/wg-easy"
>WireGuard Easy</a
>
© 2021-2024 by
({{ globalStore.currentRelease }}) © 2021-2024 by
<a
class="hover:underline"
target="_blank"
@ -32,4 +32,6 @@
</footer>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
const globalStore = useGlobalStore();
</script>

2
src/app/layouts/Header.vue

@ -63,7 +63,7 @@
</div>
<div class="text-sm text-gray-400 dark:text-neutral-400 mb-5" />
<div
v-if="globalStore.latestRelease"
v-if="globalStore.updateAvailable && globalStore.latestRelease"
class="bg-red-800 dark:bg-red-100 p-4 text-white dark:text-red-600 text-sm font-small mb-10 rounded-md shadow-lg"
:title="`v${globalStore.currentRelease} → v${globalStore.latestRelease.version}`"
>

12
src/app/stores/global.ts

@ -6,6 +6,7 @@ export const useGlobalStore = defineStore('Global', () => {
const latestRelease = ref<null | { version: string; changelog: string }>(
null
);
const updateAvailable = ref(false);
const features = ref({
trafficStats: {
enabled: false,
@ -25,7 +26,7 @@ export const useGlobalStore = defineStore('Global', () => {
const { availableLocales, locale } = useI18n();
async function fetchRelease() {
async function setLanguage() {
const { data: lang } = await api.getLang();
if (
lang.value !== getItem('lang') &&
@ -34,19 +35,18 @@ export const useGlobalStore = defineStore('Global', () => {
setItem('lang', lang.value!);
locale.value = lang.value!;
}
}
async function fetchRelease() {
const { data: release } = await api.getRelease();
if (!release.value) {
return;
}
if (!release.value.updateAvailable) {
return;
}
currentRelease.value = release.value.currentRelease;
latestRelease.value = release.value.latestRelease;
updateAvailable.value = release.value.updateAvailable;
}
async function fetchFeatures() {
@ -67,7 +67,9 @@ export const useGlobalStore = defineStore('Global', () => {
features,
currentRelease,
latestRelease,
updateAvailable,
fetchRelease,
fetchFeatures,
setLanguage,
};
});

3
src/server/api/release.get.ts

@ -1,8 +1,7 @@
import { gt } from 'semver';
export default defineEventHandler(async () => {
// TODO: cache this
const latestRelease = await fetchLatestRelease();
const latestRelease = await cachedFetchLatestRelease();
const updateAvailable = gt(latestRelease.version, RELEASE);
return {
currentRelease: RELEASE,

2
src/server/utils/config.ts

@ -5,7 +5,7 @@ import type { Database } from '~~/services/database/repositories/database';
import { parseCidr } from 'cidr-tools';
import { stringifyIp } from 'ip-bigint';
export const RELEASE = packageJson.version;
export const RELEASE = 'v' + packageJson.version;
export const SERVER_DEBUG = debug('Server');

27
src/server/utils/release.ts

@ -3,7 +3,30 @@ type GithubRelease = {
body: string;
};
export async function fetchLatestRelease() {
/**
* Cache function for 1 hour
*/
function cacheFunction<T>(fn: () => T): () => T {
let cache: { value: T; expiry: number } | null = null;
return (): T => {
const now = Date.now();
if (cache && cache.expiry > now) {
return cache.value;
}
const result = fn();
cache = {
value: result,
expiry: now + 3600000,
};
return result;
};
}
async function fetchLatestRelease() {
try {
const response = await $fetch<GithubRelease>(
'https://api.github.com/repos/wg-easy/wg-easy/releases/latest',
@ -25,3 +48,5 @@ export async function fetchLatestRelease() {
});
}
}
export const cachedFetchLatestRelease = cacheFunction(fetchLatestRelease);

Loading…
Cancel
Save