Skip to content
Snippets Groups Projects
about-misskey.vue 10.3 KiB
Newer Older
<MkStickyContainer>
	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
syuilo's avatar
syuilo committed
	<div style="overflow: clip;">
		<MkSpacer :content-max="600" :margin-min="20">
syuilo's avatar
syuilo committed
			<div class="_gaps_m znqjceqz">
syuilo's avatar
syuilo committed
				<div v-panel class="about">
					<div ref="containerEl" class="container" :class="{ playing: easterEggEngine != null }">
						<img src="/client-assets/about-icon.png" alt="" class="icon" draggable="false" @load="iconLoaded" @click="gravity"/>
						<div class="misskey">Misskey</div>
						<div class="version">v{{ version }}</div>
syuilo's avatar
syuilo committed
						<span v-for="emoji in easterEggEmojis" :key="emoji.id" class="emoji" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }">
							<MkCustomEmoji v-if="emoji.emoji[0] === ':'" class="emoji" :name="emoji.emoji" :normal="true" :no-style="true"/>
							<MkEmoji v-else class="emoji" :emoji="emoji.emoji" :normal="true" :no-style="true"/>
						</span>
syuilo's avatar
syuilo committed
					</div>
					<button v-if="thereIsTreasure" class="_button treasure" @click="getTreasure"><img src="/fluent-emoji/1f3c6.png" class="treasureImg"></button>
syuilo's avatar
syuilo committed
				<div style="text-align: center;">
					{{ i18n.ts._aboutMisskey.about }}<br><a href="https://misskey-hub.net/docs/misskey.html" target="_blank" class="_link">{{ i18n.ts.learnMore }}</a>
syuilo's avatar
syuilo committed
				</div>
syuilo's avatar
syuilo committed
				<div style="text-align: center;">
					<MkButton primary rounded inline @click="iLoveMisskey">I <Mfm text="$[jelly ❤]"/> #Misskey</MkButton>
syuilo's avatar
syuilo committed
				</div>
				<FormSection>
					<div class="_formLinks">
						<FormLink to="https://github.com/misskey-dev/misskey" external>
syuilo's avatar
syuilo committed
							<template #icon><i class="ti ti-code"></i></template>
							{{ i18n.ts._aboutMisskey.source }}
							<template #suffix>GitHub</template>
						</FormLink>
						<FormLink to="https://crowdin.com/project/misskey" external>
syuilo's avatar
syuilo committed
							<template #icon><i class="ti ti-language-hiragana"></i></template>
							{{ i18n.ts._aboutMisskey.translation }}
							<template #suffix>Crowdin</template>
						</FormLink>
						<FormLink to="https://www.patreon.com/syuilo" external>
syuilo's avatar
syuilo committed
							<template #icon><i class="ti ti-pig-money"></i></template>
							{{ i18n.ts._aboutMisskey.donate }}
							<template #suffix>Patreon</template>
						</FormLink>
					</div>
				</FormSection>
				<FormSection>
					<template #label>{{ i18n.ts._aboutMisskey.contributors }}</template>
syuilo's avatar
syuilo committed
					<div :class="$style.contributors">
						<a href="https://github.com/syuilo" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/4439005?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@syuilo</span>
						</a>
						<a href="https://github.com/tamaina" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/7973572?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@tamaina</span>
						</a>
						<a href="https://github.com/acid-chicken" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/20679825?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@acid-chicken</span>
						</a>
						<a href="https://github.com/rinsuki" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/6533808?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@rinsuki</span>
						</a>
						<a href="https://github.com/mei23" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/30769358?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@mei23</span>
						</a>
						<a href="https://github.com/robflop" target="_blank" :class="$style.contributor">
							<img src="https://avatars.githubusercontent.com/u/8159402?v=4" :class="$style.contributorAvatar">
							<span :class="$style.contributorUsername">@robflop</span>
						</a>
					</div>
					<template #caption><MkLink url="https://github.com/misskey-dev/misskey/graphs/contributors">{{ i18n.ts._aboutMisskey.allContributors }}</MkLink></template>
				</FormSection>
				<FormSection>
					<template #label><Mfm text="$[jelly ❤]"/> {{ i18n.ts._aboutMisskey.patrons }}</template>
syuilo's avatar
syuilo committed
					<div :class="$style.patronsWithIcon">
						<div v-for="patron in patronsWithIcon" :class="$style.patronWithIcon">
							<img :src="patron.icon" :class="$style.patronIcon">
							<span :class="$style.patronName">{{ patron.name }}</span>
						</div>
					</div>
					<div style="margin-top: 16px; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); grid-gap: 12px;">
syuilo's avatar
syuilo committed
						<div v-for="patron in patrons" :key="patron">{{ patron }}</div>
					</div>
					<p>{{ i18n.ts._aboutMisskey.morePatrons }}</p>
				</FormSection>
syuilo's avatar
syuilo committed
				<FormSection>
					<template #label>Credits</template>
					<p>Misskeyで使われる画像の一部は、許可を得て「あの子がこっちを見てるメーカー」で作成したものが含まれます。</p>
				</FormSection>
			</div>
		</MkSpacer>
	</div>
</MkStickyContainer>
<script lang="ts" setup>
import { nextTick, onBeforeUnmount } from 'vue';
syuilo's avatar
syuilo committed
import { version } from '@/config';
syuilo's avatar
syuilo committed
import FormLink from '@/components/form/link.vue';
import FormSection from '@/components/form/section.vue';
import MkButton from '@/components/MkButton.vue';
import MkLink from '@/components/MkLink.vue';
syuilo's avatar
syuilo committed
import { physics } from '@/scripts/physics';
import { i18n } from '@/i18n';
import { defaultStore } from '@/store';
import * as os from '@/os';
import { definePageMetadata } from '@/scripts/page-metadata';
syuilo's avatar
syuilo committed
import { claimAchievement, claimedAchievements } from '@/scripts/achievements';
import { $i } from '@/account';
syuilo's avatar
syuilo committed
const patronsWithIcon = [{
	name: 'カイヤン',
	icon: 'https://misskey-hub.net/patrons/a2820716883e408cb87773e377ce7c8d.jpg',
syuilo's avatar
syuilo committed
}, {
	name: 'だれかさん',
	icon: 'https://misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg',
syuilo's avatar
syuilo committed
}, {
	name: 'narazaka',
	icon: 'https://misskey-hub.net/patrons/e3affff31ffb4877b1196c7360abc3e5.jpg',
syuilo's avatar
syuilo committed
}];

syuilo's avatar
syuilo committed
const patrons = [
syuilo's avatar
syuilo committed
	'まっちゃとーにゅ',
syuilo's avatar
syuilo committed
	'mametsuko',
syuilo's avatar
syuilo committed
	'noellabo',
syuilo's avatar
syuilo committed
	'AureoleArk',
syuilo's avatar
syuilo committed
	'Gargron',
syuilo's avatar
syuilo committed
	'Nokotaro Takeda',
syuilo's avatar
syuilo committed
	'Suji Yan',
syuilo's avatar
syuilo committed
	'oi_yekssim',
	'regtan',
syuilo's avatar
syuilo committed
	'Hekovic',
syuilo's avatar
syuilo committed
	'nenohi',
syuilo's avatar
syuilo committed
	'Gitmo Life Services',
syuilo's avatar
syuilo committed
	'naga_rus',
	'Efertone',
syuilo's avatar
syuilo committed
	'Melilot',
syuilo's avatar
syuilo committed
	'motcha',
syuilo's avatar
syuilo committed
	'nanami kan',
	'sevvie Rose',
	'Hayato Ishikawa',
	'Puniko',
	'skehmatics',
syuilo's avatar
syuilo committed
	'Quinton Macejkovic',
syuilo's avatar
syuilo committed
	'YUKIMOCHI',
syuilo's avatar
syuilo committed
	'dansup',
syuilo's avatar
syuilo committed
	'mewl hayabusa',
syuilo's avatar
syuilo committed
	'Emilis',
	'Fristi',
syuilo's avatar
syuilo committed
	'makokunsan',
syuilo's avatar
syuilo committed
	'chidori ninokura',
syuilo's avatar
syuilo committed
	'Peter G.',
syuilo's avatar
syuilo committed
	'見当かなみ',
	'natalie',
syuilo's avatar
syuilo committed
	'Maronu',
	'Steffen K9',
syuilo's avatar
syuilo committed
	'takimura',
	'sikyosyounin',
syuilo's avatar
syuilo committed
	'Nesakko',
syuilo's avatar
syuilo committed
	'YuzuRyo61',
syuilo's avatar
syuilo committed
	'blackskye',
syuilo's avatar
syuilo committed
	'sheeta.s',
	'osapon',
syuilo's avatar
syuilo committed
	'public_yusuke',
syuilo's avatar
syuilo committed
	'CG',
syuilo's avatar
syuilo committed
	'吴浥',
	't_w',
	'Jerry',
syuilo's avatar
syuilo committed
	'nafuchoco',
	'Takumi Sugita',
syuilo's avatar
syuilo committed
	'GLaTAN',
	'mkatze',
syuilo's avatar
syuilo committed
	'kabo2468y',
syuilo's avatar
syuilo committed
	'mydarkstar',
syuilo's avatar
syuilo committed
	'Roujo',
syuilo's avatar
syuilo committed
	'DignifiedSilence',
syuilo's avatar
syuilo committed
	'uroco @99',
	'totokoro',
syuilo's avatar
syuilo committed
	'うし',
	'kiritan',
	'weepjp',
	'Liaizon Wakest',
	'Duponin',
	'Blue',
	'Naoki Hirayama',
syuilo's avatar
syuilo committed
	'wara',
syuilo's avatar
syuilo committed
	'Wataru Manji (manji0)',
	'みなしま',
	'kanoy',
	'xianon',
syuilo's avatar
syuilo committed
	'Denshi',
	'Osushimaru',
syuilo's avatar
syuilo committed
	'にょんへら',
	'おのだい',
	'Leni',
	'oss',
	'Weeble',
	'蝉暮せせせ',
Kainoa Kanter's avatar
Kainoa Kanter committed
	'ThatOneCalculator',
syuilo's avatar
syuilo committed
	'あめ玉',
syuilo's avatar
syuilo committed
let thereIsTreasure = $ref($i && !claimedAchievements.includes('foundTreasure'));

let easterEggReady = false;
let easterEggEmojis = $ref([]);
let easterEggEngine = $ref(null);
const containerEl = $shallowRef<HTMLElement>();

function iconLoaded() {
	const emojis = defaultStore.state.reactions;
	const containerWidth = containerEl.offsetWidth;
	for (let i = 0; i < 32; i++) {
		easterEggEmojis.push({
			id: i.toString(),
			top: -(128 + (Math.random() * 256)),
			left: (Math.random() * containerWidth),
			emoji: emojis[Math.floor(Math.random() * emojis.length)],
		});
	}
syuilo's avatar
syuilo committed

	nextTick(() => {
		easterEggReady = true;
	});
}
syuilo's avatar
syuilo committed

function gravity() {
	if (!easterEggReady) return;
	easterEggReady = false;
	easterEggEngine = physics(containerEl);
}
syuilo's avatar
syuilo committed

function iLoveMisskey() {
	os.post({
		initialText: 'I $[jelly ❤] #Misskey',
		instant: true,
syuilo's avatar
syuilo committed
function getTreasure() {
	thereIsTreasure = false;
	claimAchievement('foundTreasure');
}

onBeforeUnmount(() => {
	if (easterEggEngine) {
		easterEggEngine.stop();
syuilo's avatar
syuilo committed
	}
const headerActions = $computed(() => []);

const headerTabs = $computed(() => []);

definePageMetadata({
	title: i18n.ts.aboutMisskey,
	icon: null,
syuilo's avatar
syuilo committed
.znqjceqz {
syuilo's avatar
syuilo committed
	> .about {
syuilo's avatar
syuilo committed
		position: relative;
		border-radius: var(--radius);

syuilo's avatar
syuilo committed
		> .treasure {
			position: absolute;
syuilo's avatar
syuilo committed
			top: 60px;
syuilo's avatar
syuilo committed
			left: 0;
			right: 0;
			margin: 0 auto;
			width: min-content;
syuilo's avatar
syuilo committed

syuilo's avatar
syuilo committed
			> .treasureImg {
				width: 25px;
				vertical-align: bottom;
syuilo's avatar
syuilo committed
			}
syuilo's avatar
syuilo committed
		}
syuilo's avatar
syuilo committed

syuilo's avatar
syuilo committed
		> .container {
			position: relative;
			text-align: center;
			padding: 16px;
syuilo's avatar
syuilo committed

syuilo's avatar
syuilo committed
			&.playing {
				&, * {
					user-select: none;
				}
syuilo's avatar
syuilo committed

syuilo's avatar
syuilo committed
				* {
					will-change: transform;
				}
syuilo's avatar
syuilo committed

syuilo's avatar
syuilo committed
				> .emoji {
					visibility: visible;
				}
			}

			> .icon {
				display: block;
				width: 80px;
				margin: 0 auto;
				border-radius: 16px;
				position: relative;
				z-index: 1;
			}

			> .misskey {
				margin: 0.75em auto 0 auto;
				width: max-content;
syuilo's avatar
syuilo committed
				position: relative;
				z-index: 1;
syuilo's avatar
syuilo committed
			}

			> .version {
				margin: 0 auto;
				width: max-content;
				opacity: 0.5;
syuilo's avatar
syuilo committed
				position: relative;
				z-index: 1;
syuilo's avatar
syuilo committed
			}
syuilo's avatar
syuilo committed

			> .emoji {
syuilo's avatar
syuilo committed
				position: absolute;
syuilo's avatar
syuilo committed
				z-index: 1;
syuilo's avatar
syuilo committed
				top: 0;
				left: 0;
				visibility: hidden;

				> .emoji {
					pointer-events: none;
					font-size: 24px;
					width: 24px;
				}
syuilo's avatar
syuilo committed
			}
		}
	}
syuilo's avatar
syuilo committed
}
</style>
syuilo's avatar
syuilo committed

<style lang="scss" module>
.contributors {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	grid-gap: 12px;
}

.contributor {
	display: flex;
	align-items: center;
	padding: 12px;
	background: var(--buttonBg);
	border-radius: 6px;

	&:hover {
		text-decoration: none;
		background: var(--buttonHoverBg);
	}

	&.active {
		color: var(--accent);
		background: var(--buttonHoverBg);
	}
}

.contributorAvatar {
	width: 30px;
	border-radius: 100%;
}

.contributorUsername {
	margin-left: 12px;
}
syuilo's avatar
syuilo committed

.patronsWithIcon {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	grid-gap: 12px;
}

.patronWithIcon {
	display: flex;
	align-items: center;
	padding: 12px;
	background: var(--buttonBg);
	border-radius: 6px;
}

.patronIcon {
	width: 24px;
	border-radius: 100%;
}

.patronName {
	margin-left: 12px;
}
syuilo's avatar
syuilo committed
</style>