mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-01 10:25:39 +02:00
* feat: split entry file by locale name
* chore: とりあえず transform hook で雑に分割
* chore: とりあえず transform 結果をいい感じに
* chore: concurrent buildで高速化
* chore: vite ではローケルのないものをビルドして後処理でどうにかするように
* chore: 後処理のためにi18n.jを単体になるように切り出す
* chore: use typescript
* chore: remove unref(i18n) in vite build process
* chore: inline variable
* fix: build error
* fix: i18n.ts.something.replaceAll() become error
* chore: ignore export specifier from error
* chore: support i18n.tsx as object
* chore: process literal for all files
* chore: split config and locale
* chore: inline locale name
* chore: remove updating locale in boot common
* chore: use top-level await to load locales
* chore: inline locale
* chore: remove loading locale from boot.js
* chore: remove loading locale from boot.js
* コメント追加
* fix test; fetchに失敗する
* import削除ログをdebugレベルに
* fix: watch pug
* chore: use hash for entry files
* chore: remove es-module-lexer from dependencies
* chore: move to frontend-builder
* chore: use inline locale in embed
* chore: refetch json on hot reload
* feat: store localization related to boot.js in backend in bootloaderLocales localstorage
* 応急処置を戻す
* fix spex
* fix `Using i18n identifier "e" directly. Skipping inlining.` warning
* refactor: use scriptsDir parameter
* chore: remove i18n from depmap
* chore: make build crash if errors
* error -> warn few conditions
* use inline object
* update localstorage keys
* remove accessing locale localstorage
* fix: failed to process i18n.tsx.aaa({x:i18n.bbb})
181 lines
5.2 KiB
Vue
181 lines
5.2 KiB
Vue
<!--
|
||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||
SPDX-License-Identifier: AGPL-3.0-only
|
||
-->
|
||
|
||
<template>
|
||
<div class="_gaps_m" :class="$style.extInstallerRoot">
|
||
<div :class="$style.extInstallerIconWrapper">
|
||
<i v-if="isPlugin" class="ti ti-plug"></i>
|
||
<i v-else-if="isTheme" class="ti ti-palette"></i>
|
||
<!-- 拡張用? -->
|
||
<i v-else class="ti ti-download"></i>
|
||
</div>
|
||
|
||
<h2 v-if="isPlugin" :class="$style.extInstallerTitle">{{ i18n.ts._externalResourceInstaller._plugin.title }}</h2>
|
||
<h2 v-else-if="isTheme" :class="$style.extInstallerTitle">{{ i18n.ts._externalResourceInstaller._theme.title }}</h2>
|
||
|
||
<MkInfo :warn="true">{{ i18n.ts._externalResourceInstaller.checkVendorBeforeInstall }}</MkInfo>
|
||
|
||
<div v-if="extension.type === 'plugin'" class="_gaps_s">
|
||
<MkFolder :defaultOpen="true">
|
||
<template #icon><i class="ti ti-info-circle"></i></template>
|
||
<template #label>{{ i18n.ts.metadata }}</template>
|
||
|
||
<div class="_gaps_s">
|
||
<FormSplit>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.name }}</template>
|
||
<template #value>{{ extension.meta.name }}</template>
|
||
</MkKeyValue>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.author }}</template>
|
||
<template #value>{{ extension.meta.author }}</template>
|
||
</MkKeyValue>
|
||
</FormSplit>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.description }}</template>
|
||
<template #value>{{ extension.meta.description ?? i18n.ts.none }}</template>
|
||
</MkKeyValue>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.version }}</template>
|
||
<template #value>{{ extension.meta.version }}</template>
|
||
</MkKeyValue>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.permission }}</template>
|
||
<template #value>
|
||
<ul v-if="extension.meta.permissions && extension.meta.permissions.length > 0" :class="$style.extInstallerKVList">
|
||
<li v-for="permission in extension.meta.permissions" :key="permission">{{ i18n.ts._permissions[permission] }}</li>
|
||
</ul>
|
||
<template v-else>{{ i18n.ts.none }}</template>
|
||
</template>
|
||
</MkKeyValue>
|
||
</div>
|
||
</MkFolder>
|
||
|
||
<MkFolder :withSpacer="false">
|
||
<template #icon><i class="ti ti-code"></i></template>
|
||
<template #label>{{ i18n.ts._plugin.viewSource }}</template>
|
||
|
||
<MkCode :code="extension.raw"/>
|
||
</MkFolder>
|
||
</div>
|
||
<div v-else-if="extension.type === 'theme'" class="_gaps_s">
|
||
<MkFolder :defaultOpen="true">
|
||
<template #icon><i class="ti ti-info-circle"></i></template>
|
||
<template #label>{{ i18n.ts.metadata }}</template>
|
||
|
||
<div class="_gaps_s">
|
||
<FormSplit>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.name }}</template>
|
||
<template #value>{{ extension.meta.name }}</template>
|
||
</MkKeyValue>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts.author }}</template>
|
||
<template #value>{{ extension.meta.author }}</template>
|
||
</MkKeyValue>
|
||
</FormSplit>
|
||
<MkKeyValue>
|
||
<template #key>{{ i18n.ts._externalResourceInstaller._meta.base }}</template>
|
||
<template #value>{{ { light: i18n.ts.light, dark: i18n.ts.dark, none: i18n.ts.none }[extension.meta.base ?? 'none'] }}</template>
|
||
</MkKeyValue>
|
||
</div>
|
||
</MkFolder>
|
||
|
||
<MkFolder :withSpacer="false">
|
||
<template #icon><i class="ti ti-code"></i></template>
|
||
<template #label>{{ i18n.ts._theme.code }}</template>
|
||
|
||
<MkCode :code="extension.raw"/>
|
||
</MkFolder>
|
||
</div>
|
||
|
||
<slot name="additionalInfo"/>
|
||
|
||
<div class="_buttonsCenter">
|
||
<MkButton danger rounded large @click="emits('cancel')"><i class="ti ti-x"></i> {{ i18n.ts.cancel }}</MkButton>
|
||
<MkButton gradate rounded large @click="emits('confirm')"><i class="ti ti-download"></i> {{ i18n.ts.install }}</MkButton>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
export type Extension = {
|
||
type: 'plugin';
|
||
raw: string;
|
||
meta: {
|
||
name: string;
|
||
version: string;
|
||
author: string;
|
||
description?: string;
|
||
permissions?: string[];
|
||
config?: Record<string, unknown>;
|
||
};
|
||
} | {
|
||
type: 'theme';
|
||
raw: string;
|
||
meta: {
|
||
name: string;
|
||
author: string;
|
||
base?: 'light' | 'dark';
|
||
};
|
||
};
|
||
</script>
|
||
<script lang="ts" setup>
|
||
import { computed } from 'vue';
|
||
import MkButton from '@/components/MkButton.vue';
|
||
import FormSection from '@/components/form/section.vue';
|
||
import FormSplit from '@/components/form/split.vue';
|
||
import MkCode from '@/components/MkCode.vue';
|
||
import MkInfo from '@/components/MkInfo.vue';
|
||
import MkFolder from '@/components/MkFolder.vue';
|
||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||
import { i18n } from '@/i18n.js';
|
||
|
||
const isPlugin = computed(() => props.extension.type === 'plugin');
|
||
const isTheme = computed(() => props.extension.type === 'theme');
|
||
|
||
const props = defineProps<{
|
||
extension: Extension;
|
||
}>();
|
||
|
||
const emits = defineEmits<{
|
||
(ev: 'confirm'): void;
|
||
(ev: 'cancel'): void;
|
||
}>();
|
||
</script>
|
||
|
||
<style lang="scss" module>
|
||
.extInstallerRoot {
|
||
border-radius: var(--MI-radius);
|
||
background: var(--MI_THEME-panel);
|
||
padding: 20px;
|
||
}
|
||
|
||
.extInstallerIconWrapper {
|
||
width: 48px;
|
||
height: 48px;
|
||
font-size: 20px;
|
||
line-height: 48px;
|
||
text-align: center;
|
||
border-radius: 50%;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
|
||
background-color: var(--MI_THEME-accentedBg);
|
||
color: var(--MI_THEME-accent);
|
||
}
|
||
|
||
.extInstallerTitle {
|
||
font-size: 1.2rem;
|
||
text-align: center;
|
||
margin: 0;
|
||
}
|
||
|
||
.extInstallerKVList {
|
||
margin-top: 0;
|
||
margin-bottom: 0;
|
||
}
|
||
</style>
|