PronounsPage/layouts/default.vue
Andrea Vos 3851c0e170 lint
2025-02-06 21:06:58 +01:00

181 lines
5.2 KiB
Vue

<script setup lang="ts">
import sorter from 'avris-sorter';
import md5 from 'js-md5';
import { useCookie } from 'nuxt/app';
import useConfig from '~/composables/useConfig.ts';
import useDark from '~/composables/useDark.ts';
import useDialogue from '~/composables/useDialogue.ts';
import { longtimeCookieSetting } from '~/src/cookieSettings.ts';
import { LoadScriptError } from '~/src/errors.ts';
import { newDate } from '~/src/helpers.ts';
import { useMainStore } from '~/store/index.ts';
// no need to be super secure, just a sign that the page is not public
const TESTER_PASSWORD_HASH = '82feeb96d60170e714df8fb062301e90';
declare global {
interface Window {
dataLayer: unknown[];
}
}
const { $translator: translator, $isGranted: isGranted, $locales: locales, $loadScript: loadScript } = useNuxtApp();
const config = useConfig();
const runtimeConfig = useRuntimeConfig();
const store = useMainStore();
useDark();
const testerPasswordCookie = useCookie('tester-password', longtimeCookieSetting);
const testerPassword = ref('');
const requiresLogin = computed((): boolean => {
return !config.macrolanguage?.enabled && (runtimeConfig.public.env === 'test' ||
config.locale !== '_' && !locales[config.locale]?.published);
});
const testerPasswordValid = computed((): boolean => {
return !!testerPasswordCookie.value && md5(testerPasswordCookie.value) === TESTER_PASSWORD_HASH;
});
const checkTesterPassword = (): void => {
testerPasswordCookie.value = testerPassword.value;
};
onMounted(() => {
sorter();
confirmAge();
loadAds();
loadGTM();
let needsRefresh = false;
const bc = new BroadcastChannel('account_switch');
bc.onmessage = (ev): void => {
if (ev.data !== store.user?.username) {
needsRefresh = true;
if (document.hasFocus()) {
needsRefresh = false;
window.location.reload();
}
}
};
window.onfocus = (): void => {
if (needsRefresh) {
needsRefresh = false;
window.location.reload();
}
};
});
const dialogue = useDialogue();
const confirmAge = async (): Promise<void> => {
if (!translator.has('footer.ageLimit') || localStorage.getItem('ageConfirmed')) {
return;
}
await dialogue.alert(translator.translate('footer.ageLimit'));
localStorage.setItem('ageConfirmed', '1');
};
const adsEnabled = computed((): boolean => {
if (isGranted()) {
const adsVisible = parseInt(localStorage.getItem('adsVisible') || '0') === 1;
if (!adsVisible) {
return false;
}
}
return !!config.ads?.enabled && import.meta.env?.APP_ENV === 'production';
});
const loadAds = async (): Promise<void> => {
if (!adsEnabled.value) {
return;
}
try {
await loadScript(
'publift',
'https://cdn.fuseplatform.net/publift/tags/2/3329/fuse.js',
);
await loadScript(
'publift-video',
'https://live.primis.tech/live/liveView.php?s=118558&schain=1.0,1!publift.com,[01H9H7XDCTSKKX1ECPR1VWQXQ9],1',
undefined,
'[data-phkey=content-0]',
);
} catch (error) {
if (error instanceof LoadScriptError) {
return;
}
throw error;
}
};
const loadGTM = async (): Promise<void> => {
if (!adsEnabled.value) {
return;
}
try {
await loadScript('gtm', 'https://www.googletagmanager.com/gtag/js?id=G-TDJEP12Q3M');
} catch (error) {
if (error instanceof LoadScriptError) {
return;
}
throw error;
}
window.dataLayer = window.dataLayer || [];
function gtag(...args: unknown[]): void {
window.dataLayer.push(args);
}
gtag('js', newDate());
gtag('config', 'G-TDJEP12Q3M');
};
</script>
<template>
<div v-if="requiresLogin && !testerPasswordValid" class="body">
<div class="container">
<div class="alert alert-warning m-3 text-center">
<Icon v="exclamation-triangle" />
This is a test server
</div>
<div class="m-3">
<div class="input-group py-1">
<input v-model="testerPassword" class="form-control" type="password" placeholder="Password" @keydown.enter.prevent="checkTesterPassword">
<button type="button" class="btn btn-primary btn-sm border" @click.prevent="checkTesterPassword">
<Icon v="sign-in" />
Sign in
</button>
</div>
<p v-if="testerPasswordCookie && !testerPasswordValid" class="small text-danger">
<Icon v="exclamation-triangle" />
Password invalid
</p>
</div>
</div>
</div>
<div v-else class="body">
<div class="flex-grow-1 vh">
<Header />
<slot></slot>
<TranslationMode />
<ScrollButton />
</div>
<Footer />
<Lightbox />
</div>
</template>
<style lang="scss">
@import "assets/variables";
@import "~avris-sorter/dist/Sorter.min.css";
.vh {
min-height: calc(100vh - #{$header-height});
}
</style>