enhance: metaをSSR HTMLに埋め込む (#13436)

* enhance: `meta`をSSR HTMLに埋め込む

* HTML Metaの有効時間を指定

* 1時間

* MetaEntityService

* JSONをPackするように

* ✌️

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
かっこかり 2024-02-23 10:47:17 +09:00 committed by GitHub
parent bf5952fd63
commit d20542c495
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 676 additions and 530 deletions

View file

@ -11,7 +11,7 @@ import { alert, confirm, popup, post, toast } from '@/os.js';
import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { $i, signout, updateAccount } from '@/account.js';
import { fetchInstance, instance } from '@/instance.js';
import { instance } from '@/instance.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { makeHotkey } from '@/scripts/hotkey.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
@ -235,12 +235,10 @@ export async function mainBoot() {
}
}
fetchInstance().then(() => {
const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {}, 'closed');
}
});
const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {}, 'closed');
}
if ('Notification' in window) {
// 許可を得ていなかったらリクエスト

View file

@ -11,13 +11,24 @@ import { DEFAULT_INFO_IMAGE_URL, DEFAULT_NOT_FOUND_IMAGE_URL, DEFAULT_SERVER_ERR
// TODO: 他のタブと永続化されたstateを同期
const cached = miLocalStorage.getItem('instance');
//#region loader
const providedMetaEl = document.getElementById('misskey_meta');
let cachedMeta = miLocalStorage.getItem('instance') ? JSON.parse(miLocalStorage.getItem('instance')!) : null;
let cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
const providedMeta = providedMetaEl && providedMetaEl.textContent ? JSON.parse(providedMetaEl.textContent) : null;
const providedAt = providedMetaEl && providedMetaEl.dataset.generatedAt ? parseInt(providedMetaEl.dataset.generatedAt) : 0;
if (providedAt > cachedAt) {
miLocalStorage.setItem('instance', JSON.stringify(providedMeta));
miLocalStorage.setItem('instanceCachedAt', providedAt.toString());
cachedMeta = providedMeta;
cachedAt = providedAt;
}
//#endregion
// TODO: instanceをリアクティブにするかは再考の余地あり
export const instance: Misskey.entities.MetaResponse = reactive(cached ? JSON.parse(cached) : {
// TODO: set default values
});
export const instance: Misskey.entities.MetaResponse = reactive(cachedMeta ?? {});
export const serverErrorImageUrl = computed(() => instance.serverErrorImageUrl ?? DEFAULT_SERVER_ERROR_IMAGE_URL);
@ -25,7 +36,15 @@ export const infoImageUrl = computed(() => instance.infoImageUrl ?? DEFAULT_INFO
export const notFoundImageUrl = computed(() => instance.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL);
export async function fetchInstance() {
export async function fetchInstance(force = false): Promise<void> {
if (!force) {
const cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
if (Date.now() - cachedAt < 1000 * 60 * 60) {
return;
}
}
const meta = await misskeyApi('meta', {
detail: false,
});
@ -35,4 +54,5 @@ export async function fetchInstance() {
}
miLocalStorage.setItem('instance', JSON.stringify(instance));
miLocalStorage.setItem('instanceCachedAt', Date.now().toString());
}

View file

@ -7,6 +7,7 @@ type Keys =
'v' |
'lastVersion' |
'instance' |
'instanceCachedAt' |
'account' |
'accounts' |
'latestDonationInfoShownAt' |

View file

@ -142,7 +142,7 @@ function save() {
turnstileSiteKey: turnstileSiteKey.value,
turnstileSecretKey: turnstileSecretKey.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}
</script>

View file

@ -169,7 +169,7 @@ function save() {
feedbackUrl: feedbackUrl.value === '' ? null : feedbackUrl.value,
manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)),
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -124,7 +124,7 @@ function save() {
smtpUser: smtpUser.value,
smtpPass: smtpPass.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -61,7 +61,7 @@ function save() {
deeplAuthKey: deeplAuthKey.value,
deeplIsPro: deeplIsPro.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -50,7 +50,7 @@ function save() {
silencedHosts: silencedHosts.value.split('\n') || [],
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -110,7 +110,7 @@ function save() {
hiddenTags: hiddenTags.value.split('\n'),
preservedUsernames: preservedUsernames.value.split('\n'),
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -143,7 +143,7 @@ function save() {
objectStorageSetPublicRead: objectStorageSetPublicRead.value,
objectStorageS3ForcePathStyle: objectStorageS3ForcePathStyle.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -73,7 +73,7 @@ function save() {
enableChartsForRemoteUser: enableChartsForRemoteUser.value,
enableChartsForFederatedInstances: enableChartsForFederatedInstances.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -56,7 +56,7 @@ function save() {
os.apiWithDialog('admin/update-meta', {
proxyAccountId: proxyAccountId.value,
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -196,7 +196,7 @@ async function init() {
enableTruemailApi.value = meta.enableTruemailApi;
truemailInstance.value = meta.truemailInstance;
truemailAuthKey.value = meta.truemailAuthKey;
bannedEmailDomains.value = meta.bannedEmailDomains?.join('\n') || "";
bannedEmailDomains.value = meta.bannedEmailDomains?.join('\n') || '';
}
function save() {
@ -221,7 +221,7 @@ function save() {
truemailAuthKey: truemailAuthKey.value,
bannedEmailDomains: bannedEmailDomains.value.split('\n'),
}).then(() => {
fetchInstance();
fetchInstance(true);
});
}

View file

@ -58,7 +58,7 @@ const save = async () => {
await os.apiWithDialog('admin/update-meta', {
serverRules: serverRules.value,
});
fetchInstance();
fetchInstance(true);
};
const remove = (index: number): void => {

View file

@ -243,7 +243,7 @@ async function save(): void {
notesPerOneAd: notesPerOneAd.value,
});
fetchInstance();
fetchInstance(true);
}
const headerTabs = computed(() => []);

View file

@ -2,14 +2,18 @@ import { unisonReload } from '@/scripts/unison-reload.js';
import * as os from '@/os.js';
import { miLocalStorage } from '@/local-storage.js';
import { fetchCustomEmojis } from '@/custom-emojis.js';
import { fetchInstance } from '@/instance.js';
export async function clearCache() {
os.waiting();
miLocalStorage.removeItem('instance');
miLocalStorage.removeItem('instanceCachedAt');
miLocalStorage.removeItem('locale');
miLocalStorage.removeItem('localeVersion');
miLocalStorage.removeItem('theme');
miLocalStorage.removeItem('emojis');
miLocalStorage.removeItem('lastEmojisFetchedAt');
await fetchInstance(true);
await fetchCustomEmojis(true);
unisonReload();
}