mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-03 11:07:00 -04:00
222 lines
6.2 KiB
Vue
222 lines
6.2 KiB
Vue
<script setup lang="ts">
|
|
import { useStorage } from '@vueuse/core';
|
|
import sorter from 'avris-sorter';
|
|
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 { executeUnlessPrerendering, sha256 } 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 = '3754c03824c4ea3b13e7b4b2d7ad35992dbf64f9ee680493fc7093bf176f49e5';
|
|
|
|
declare global {
|
|
interface Window {
|
|
dataLayer: unknown[];
|
|
gnshbrequest: {
|
|
cmd: any[];
|
|
forceInternalRequest: () => void;
|
|
};
|
|
adpushup: {
|
|
que: any[];
|
|
};
|
|
}
|
|
}
|
|
|
|
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 => {
|
|
if (config.macrolanguage?.enabled) {
|
|
return false;
|
|
}
|
|
|
|
if (runtimeConfig.public.env === 'test') {
|
|
return true;
|
|
}
|
|
|
|
if (config.locale !== '_' && !locales[config.locale]?.published) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
const testerPasswordValid = ref<boolean | undefined>();
|
|
const checkTesterPassword = async () => {
|
|
if (testerPassword.value) {
|
|
testerPasswordCookie.value = testerPassword.value;
|
|
}
|
|
if (testerPasswordCookie.value) {
|
|
testerPasswordValid.value = await sha256(testerPasswordCookie.value) === TESTER_PASSWORD_HASH;
|
|
}
|
|
};
|
|
|
|
if (requiresLogin.value) {
|
|
await checkTesterPassword();
|
|
}
|
|
|
|
onMounted(executeUnlessPrerendering(() => {
|
|
sorter();
|
|
|
|
confirmAge();
|
|
|
|
loadAds();
|
|
|
|
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 provider = useStorage<string | null>('ads-provider', null);
|
|
|
|
if (provider.value === null) {
|
|
provider.value = Math.random() < 0.7 ? 'publift' : 'pushup';
|
|
}
|
|
|
|
const adsEnabled = computed((): boolean => {
|
|
if (isGranted() && provider.value === 'none') {
|
|
return false;
|
|
}
|
|
|
|
return !!config.ads?.enabled && import.meta.env?.APP_ENV === 'production';
|
|
});
|
|
|
|
const loadAdsForProvider = {
|
|
publift: async (): Promise<void> => {
|
|
await loadScript(
|
|
'publift',
|
|
'https://cdn.fuseplatform.net/publift/tags/2/3329/fuse.js',
|
|
undefined,
|
|
'head',
|
|
);
|
|
},
|
|
geniee: async (): Promise<void> => {
|
|
window.gnshbrequest = window.gnshbrequest || { cmd: [] };
|
|
window.gnshbrequest.cmd.push(function () {
|
|
window.gnshbrequest.forceInternalRequest();
|
|
});
|
|
|
|
await loadScript(
|
|
'gpt',
|
|
'https://securepubads.g.doubleclick.net/tag/js/gpt.js',
|
|
undefined,
|
|
'head',
|
|
);
|
|
await loadScript(
|
|
'geniee',
|
|
'https://cpt.geniee.jp/hb/v1/222988/2860/wrapper.min.js',
|
|
undefined,
|
|
'head',
|
|
);
|
|
},
|
|
pushup: async (): Promise<void> => {
|
|
await loadScript(
|
|
'adpushup',
|
|
'https://cdn.adpushup.com/47589/adpushup.js',
|
|
undefined,
|
|
'head',
|
|
);
|
|
},
|
|
};
|
|
|
|
const loadAds = async (): Promise<void> => {
|
|
if (!adsEnabled.value) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
console.log('loading', provider.value);
|
|
const key = provider.value as keyof typeof loadAdsForProvider;
|
|
if (!Object.hasOwn(loadAdsForProvider, key)) {
|
|
throw new Error(`Invalid provider: ${key}`);
|
|
}
|
|
await loadAdsForProvider[key]();
|
|
} catch (error) {
|
|
if (error instanceof LoadScriptError) {
|
|
return;
|
|
}
|
|
throw error;
|
|
}
|
|
};
|
|
</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 === false" 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>
|