mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	merge: Ported cutiekeys followmouse mfm (!524)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/524 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Luna <her@mint.lgbt> Approved-by: Amelia Yukii <amelia.yukii@shourai.de>
This commit is contained in:
		
						commit
						3d0bf928a7
					
				
					 5 changed files with 184 additions and 62 deletions
				
			
		locales
packages/frontend/src
| 
						 | 
				
			
			@ -2478,6 +2478,7 @@ _moderationLogTypes:
 | 
			
		|||
  unsetUserAvatar: "Unset this user's avatar"
 | 
			
		||||
  unsetUserBanner: "Unset this user's banner"
 | 
			
		||||
_mfm:
 | 
			
		||||
  uncommonFeature: "This is not a widespread feature, it may not display properly on most other fedi software, including other Misskey forks"
 | 
			
		||||
  intro: "MFM is a markup language used on Misskey, Sharkey, Firefish, Akkoma, and more that can be used in many places. Here you can view a list of all available MFM syntax."
 | 
			
		||||
  dummy: "Sharkey expands the world of the Fediverse"
 | 
			
		||||
  mention: "Mention"
 | 
			
		||||
| 
						 | 
				
			
			@ -2542,6 +2543,8 @@ _mfm:
 | 
			
		|||
  rotateDescription: "Turns content by a specified angle."
 | 
			
		||||
  position: "Position"
 | 
			
		||||
  positionDescription: "Move content by a specified amount."
 | 
			
		||||
  followMouse: "Follow Mouse"
 | 
			
		||||
  followMouseDescription: "Content will follow the mouse. On mobile it will follow wherever the user taps."
 | 
			
		||||
  scale: "Scale"
 | 
			
		||||
  scaleDescription: "Scale content by a specified amount."
 | 
			
		||||
  foreground: "Foreground color"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										81
									
								
								packages/frontend/src/components/CkFollowMouse.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								packages/frontend/src/components/CkFollowMouse.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
<template>
 | 
			
		||||
<span ref="container" :class="$style.root">
 | 
			
		||||
	<span ref="el" :class="$style.inner" style="position: absolute">
 | 
			
		||||
		<slot></slot>
 | 
			
		||||
	</span>
 | 
			
		||||
</span>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { onMounted, onUnmounted, shallowRef } from 'vue';
 | 
			
		||||
const el = shallowRef<HTMLElement>();
 | 
			
		||||
const container = shallowRef<HTMLElement>();
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
	x: {
 | 
			
		||||
		type: Boolean,
 | 
			
		||||
		default: true,
 | 
			
		||||
	},
 | 
			
		||||
	y: {
 | 
			
		||||
		type: Boolean,
 | 
			
		||||
		default: true,
 | 
			
		||||
	},
 | 
			
		||||
	speed: {
 | 
			
		||||
		type: String,
 | 
			
		||||
		default: '0.1s',
 | 
			
		||||
	},
 | 
			
		||||
	rotateByVelocity: {
 | 
			
		||||
		type: Boolean,
 | 
			
		||||
		default: true,
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
let lastX = 0;
 | 
			
		||||
let lastY = 0;
 | 
			
		||||
let oldAngle = 0;
 | 
			
		||||
 | 
			
		||||
function lerp(a, b, alpha) {
 | 
			
		||||
	return a + alpha * (b - a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const updatePosition = (mouseEvent: MouseEvent) => {
 | 
			
		||||
	if (el.value && container.value) {
 | 
			
		||||
		const containerRect = container.value.getBoundingClientRect();
 | 
			
		||||
		const newX = mouseEvent.clientX - containerRect.left;
 | 
			
		||||
		const newY = mouseEvent.clientY - containerRect.top;
 | 
			
		||||
		let transform = `translate(calc(${props.x ? newX : 0}px - 50%), calc(${props.y ? newY : 0}px - 50%))`;
 | 
			
		||||
		if (props.rotateByVelocity) {
 | 
			
		||||
			const deltaX = newX - lastX;
 | 
			
		||||
			const deltaY = newY - lastY;
 | 
			
		||||
			const angle = lerp(
 | 
			
		||||
				oldAngle,
 | 
			
		||||
				Math.atan2(deltaY, deltaX) * (180 / Math.PI),
 | 
			
		||||
				0.1,
 | 
			
		||||
			);
 | 
			
		||||
			transform += ` rotate(${angle}deg)`;
 | 
			
		||||
			oldAngle = angle;
 | 
			
		||||
		}
 | 
			
		||||
		el.value.style.transform = transform;
 | 
			
		||||
		el.value.style.transition = `transform ${props.speed}`;
 | 
			
		||||
		lastX = newX;
 | 
			
		||||
		lastY = newY;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
	window.addEventListener('mousemove', updatePosition);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
	window.removeEventListener('mousemove', updatePosition);
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" module>
 | 
			
		||||
.root {
 | 
			
		||||
	position: relative;
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
.inner {
 | 
			
		||||
	transform-origin: center center;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -13,13 +13,13 @@
 | 
			
		|||
		<MkSpacer :contentMax="800">
 | 
			
		||||
			<div class="mfm-cheat-sheet">
 | 
			
		||||
				<div>{{ i18n.ts._mfm.intro }}</div>
 | 
			
		||||
				<br />
 | 
			
		||||
				<br/>
 | 
			
		||||
				<div class="section _block">
 | 
			
		||||
					<div class="title">{{ i18n.ts._mfm.mention }}</div>
 | 
			
		||||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.mentionDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_mention" />
 | 
			
		||||
							<Mfm :text="preview_mention"/>
 | 
			
		||||
							<MkTextarea v-model="preview_mention"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +29,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.hashtagDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_hashtag" />
 | 
			
		||||
							<Mfm :text="preview_hashtag"/>
 | 
			
		||||
							<MkTextarea v-model="preview_hashtag"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.linkDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_link" />
 | 
			
		||||
							<Mfm :text="preview_link"/>
 | 
			
		||||
							<MkTextarea v-model="preview_link"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.emojiDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_emoji" />
 | 
			
		||||
							<Mfm :text="preview_emoji"/>
 | 
			
		||||
							<MkTextarea v-model="preview_emoji"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.boldDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_bold" />
 | 
			
		||||
							<Mfm :text="preview_bold"/>
 | 
			
		||||
							<MkTextarea v-model="preview_bold"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.smallDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_small" />
 | 
			
		||||
							<Mfm :text="preview_small"/>
 | 
			
		||||
							<MkTextarea v-model="preview_small"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +79,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.quoteDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_quote" />
 | 
			
		||||
							<Mfm :text="preview_quote"/>
 | 
			
		||||
							<MkTextarea v-model="preview_quote"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.centerDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_center" />
 | 
			
		||||
							<Mfm :text="preview_center"/>
 | 
			
		||||
							<MkTextarea v-model="preview_center"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.inlineCodeDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_inlineCode" />
 | 
			
		||||
							<Mfm :text="preview_inlineCode"/>
 | 
			
		||||
							<MkTextarea v-model="preview_inlineCode"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.blockCodeDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_blockCode" />
 | 
			
		||||
							<Mfm :text="preview_blockCode"/>
 | 
			
		||||
							<MkTextarea v-model="preview_blockCode"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +119,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.inlineMathDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_inlineMath" />
 | 
			
		||||
							<Mfm :text="preview_inlineMath"/>
 | 
			
		||||
							<MkTextarea v-model="preview_inlineMath"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.blockMathDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_blockMath" />
 | 
			
		||||
							<Mfm :text="preview_blockMath"/>
 | 
			
		||||
							<MkTextarea v-model="preview_blockMath"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.searchDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_search" />
 | 
			
		||||
							<Mfm :text="preview_search"/>
 | 
			
		||||
							<MkTextarea v-model="preview_search"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +149,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.flipDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_flip" />
 | 
			
		||||
							<Mfm :text="preview_flip"/>
 | 
			
		||||
							<MkTextarea v-model="preview_flip"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +159,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.fontDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_font" />
 | 
			
		||||
							<Mfm :text="preview_font"/>
 | 
			
		||||
							<MkTextarea v-model="preview_font"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +169,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.x2Description }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_x2" />
 | 
			
		||||
							<Mfm :text="preview_x2"/>
 | 
			
		||||
							<MkTextarea v-model="preview_x2"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -179,7 +179,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.x3Description }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_x3" />
 | 
			
		||||
							<Mfm :text="preview_x3"/>
 | 
			
		||||
							<MkTextarea v-model="preview_x3"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +189,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.x4Description }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_x4" />
 | 
			
		||||
							<Mfm :text="preview_x4"/>
 | 
			
		||||
							<MkTextarea v-model="preview_x4"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.blurDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_blur" />
 | 
			
		||||
							<Mfm :text="preview_blur"/>
 | 
			
		||||
							<MkTextarea v-model="preview_blur"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -209,7 +209,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.jellyDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_jelly" />
 | 
			
		||||
							<Mfm :text="preview_jelly"/>
 | 
			
		||||
							<MkTextarea v-model="preview_jelly"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -219,7 +219,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.tadaDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_tada" />
 | 
			
		||||
							<Mfm :text="preview_tada"/>
 | 
			
		||||
							<MkTextarea v-model="preview_tada"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +229,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.jumpDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_jump" />
 | 
			
		||||
							<Mfm :text="preview_jump"/>
 | 
			
		||||
							<MkTextarea v-model="preview_jump"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +239,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.bounceDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_bounce" />
 | 
			
		||||
							<Mfm :text="preview_bounce"/>
 | 
			
		||||
							<MkTextarea v-model="preview_bounce"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +249,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.spinDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_spin" />
 | 
			
		||||
							<Mfm :text="preview_spin"/>
 | 
			
		||||
							<MkTextarea v-model="preview_spin"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +259,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.shakeDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_shake" />
 | 
			
		||||
							<Mfm :text="preview_shake"/>
 | 
			
		||||
							<MkTextarea v-model="preview_shake"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -269,7 +269,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.twitchDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_twitch" />
 | 
			
		||||
							<Mfm :text="preview_twitch"/>
 | 
			
		||||
							<MkTextarea v-model="preview_twitch"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +279,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.rainbowDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_rainbow" />
 | 
			
		||||
							<Mfm :text="preview_rainbow"/>
 | 
			
		||||
							<MkTextarea v-model="preview_rainbow"><template #label>MFM</template></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +289,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.sparkleDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_sparkle" />
 | 
			
		||||
							<Mfm :text="preview_sparkle"/>
 | 
			
		||||
							<MkTextarea v-model="preview_sparkle"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +299,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.rotateDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_rotate" />
 | 
			
		||||
							<Mfm :text="preview_rotate"/>
 | 
			
		||||
							<MkTextarea v-model="preview_rotate"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -309,17 +309,29 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.positionDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_position" />
 | 
			
		||||
							<Mfm :text="preview_position"/>
 | 
			
		||||
							<MkTextarea v-model="preview_position"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="section _block" style="overflow: hidden">
 | 
			
		||||
					<div class="title">{{ i18n.ts._mfm.followMouse }}</div>
 | 
			
		||||
					<MkInfo warn>{{  i18n.ts._mfm.uncommonFeature }}</MkInfo>
 | 
			
		||||
					<br/>
 | 
			
		||||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.followMouseDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_followmouse"/>
 | 
			
		||||
							<MkTextarea v-model="preview_followmouse"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="section _block">
 | 
			
		||||
					<div class="title">{{ i18n.ts._mfm.scale }}</div>
 | 
			
		||||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.scaleDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_scale" />
 | 
			
		||||
							<Mfm :text="preview_scale"/>
 | 
			
		||||
							<MkTextarea v-model="preview_scale"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +341,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.foregroundDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_fg" />
 | 
			
		||||
							<Mfm :text="preview_fg"/>
 | 
			
		||||
							<MkTextarea v-model="preview_fg"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +351,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.backgroundDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_bg" />
 | 
			
		||||
							<Mfm :text="preview_bg"/>
 | 
			
		||||
							<MkTextarea v-model="preview_bg"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +361,7 @@
 | 
			
		|||
					<div class="content">
 | 
			
		||||
						<p>{{ i18n.ts._mfm.plainDescription }}</p>
 | 
			
		||||
						<div class="preview">
 | 
			
		||||
							<Mfm :text="preview_plain" />
 | 
			
		||||
							<Mfm :text="preview_plain"/>
 | 
			
		||||
							<MkTextarea v-model="preview_plain"><span>MFM</span></MkTextarea>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -362,18 +374,19 @@
 | 
			
		|||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import MkInfo from './MkInfo.vue';
 | 
			
		||||
import MkWindow from '@/components/MkWindow.vue';
 | 
			
		||||
import MkTextarea from '@/components/MkTextarea.vue';
 | 
			
		||||
import { i18n } from "@/i18n.js";
 | 
			
		||||
import { i18n } from '@/i18n.js';
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
	(ev: 'closed'): void;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const preview_mention = ref("@example");
 | 
			
		||||
const preview_hashtag = ref("#test");
 | 
			
		||||
const preview_mention = ref('@example');
 | 
			
		||||
const preview_hashtag = ref('#test');
 | 
			
		||||
const preview_link = ref(`[${i18n.ts._mfm.dummy}](https://joinsharkey.org)`);
 | 
			
		||||
const preview_emoji = ref(`:heart:`);
 | 
			
		||||
const preview_emoji = ref(':heart:');
 | 
			
		||||
const preview_bold = ref(`**${i18n.ts._mfm.dummy}**`);
 | 
			
		||||
const preview_small = ref(
 | 
			
		||||
	`<small>${i18n.ts._mfm.dummy}</small>`,
 | 
			
		||||
| 
						 | 
				
			
			@ -386,33 +399,33 @@ const preview_blockCode = ref(
 | 
			
		|||
	'```\n~ (#i, 100) {\n\t<: ? ((i % 15) = 0) "FizzBuzz"\n\t\t.? ((i % 3) = 0) "Fizz"\n\t\t.? ((i % 5) = 0) "Buzz"\n\t\t. i\n}\n```',
 | 
			
		||||
);
 | 
			
		||||
const preview_inlineMath = ref(
 | 
			
		||||
	"\\(x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\)",
 | 
			
		||||
	'\\(x= \\frac{-b\' \\pm \\sqrt{(b\')^2-ac}}{a}\\)',
 | 
			
		||||
);
 | 
			
		||||
const preview_blockMath = ref("\\[x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\]");
 | 
			
		||||
const preview_blockMath = ref('\\[x= \\frac{-b\' \\pm \\sqrt{(b\')^2-ac}}{a}\\]');
 | 
			
		||||
const preview_quote = ref(`> ${i18n.ts._mfm.dummy}`);
 | 
			
		||||
const preview_search = ref(
 | 
			
		||||
	`${i18n.ts._mfm.dummy} [search]\n${i18n.ts._mfm.dummy} [検索]`,
 | 
			
		||||
);
 | 
			
		||||
const preview_jelly = ref(
 | 
			
		||||
	"$[jelly 🍮] $[jelly.speed=3s 🍮] $[jelly.delay=3s 🍮] $[jelly.loop=3 🍮]",
 | 
			
		||||
	'$[jelly 🍮] $[jelly.speed=3s 🍮] $[jelly.delay=3s 🍮] $[jelly.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_tada = ref(
 | 
			
		||||
	"$[tada 🍮] $[tada.speed=3s 🍮] $[tada.delay=3s 🍮] $[tada.loop=3 🍮]",
 | 
			
		||||
	'$[tada 🍮] $[tada.speed=3s 🍮] $[tada.delay=3s 🍮] $[tada.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_jump = ref(
 | 
			
		||||
	"$[jump 🍮] $[jump.speed=3s 🍮] $[jump.delay=3s 🍮] $[jump.loop=3 🍮]",
 | 
			
		||||
	'$[jump 🍮] $[jump.speed=3s 🍮] $[jump.delay=3s 🍮] $[jump.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_bounce = ref(
 | 
			
		||||
	"$[bounce 🍮] $[bounce.speed=3s 🍮] $[bounce.delay=3s 🍮] $[bounce.loop=3 🍮]",
 | 
			
		||||
	'$[bounce 🍮] $[bounce.speed=3s 🍮] $[bounce.delay=3s 🍮] $[bounce.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_shake = ref(
 | 
			
		||||
	"$[shake 🍮] $[shake.speed=3s 🍮] $[shake.delay=3s 🍮] $[shake.loop=3 🍮]",
 | 
			
		||||
	'$[shake 🍮] $[shake.speed=3s 🍮] $[shake.delay=3s 🍮] $[shake.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_twitch = ref(
 | 
			
		||||
	"$[twitch 🍮] $[twitch.speed=3s 🍮] $[twitch.delay=3s 🍮] $[twitch.loop=3 🍮]",
 | 
			
		||||
	'$[twitch 🍮] $[twitch.speed=3s 🍮] $[twitch.delay=3s 🍮] $[twitch.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_spin = ref(
 | 
			
		||||
	"$[spin 🍮] $[spin.left 🍮] $[spin.alternate 🍮]\n$[spin.x 🍮] $[spin.x,left 🍮] $[spin.x,alternate 🍮]\n$[spin.y 🍮] $[spin.y,left 🍮] $[spin.y,alternate 🍮]\n\n$[spin.speed=3s 🍮] $[spin.delay=3s 🍮] $[spin.loop=3 🍮]",
 | 
			
		||||
	'$[spin 🍮] $[spin.left 🍮] $[spin.alternate 🍮]\n$[spin.x 🍮] $[spin.x,left 🍮] $[spin.x,alternate 🍮]\n$[spin.y 🍮] $[spin.y,left 🍮] $[spin.y,alternate 🍮]\n\n$[spin.speed=3s 🍮] $[spin.delay=3s 🍮] $[spin.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_flip = ref(
 | 
			
		||||
	`$[flip ${i18n.ts._mfm.dummy}]\n$[flip.v ${i18n.ts._mfm.dummy}]\n$[flip.h,v ${i18n.ts._mfm.dummy}]`,
 | 
			
		||||
| 
						 | 
				
			
			@ -420,25 +433,26 @@ const preview_flip = ref(
 | 
			
		|||
const preview_font = ref(
 | 
			
		||||
	`$[font.serif ${i18n.ts._mfm.dummy}]\n$[font.monospace ${i18n.ts._mfm.dummy}]`,
 | 
			
		||||
);
 | 
			
		||||
const preview_x2 = ref("$[x2 🍮]");
 | 
			
		||||
const preview_x3 = ref("$[x3 🍮]");
 | 
			
		||||
const preview_x4 = ref("$[x4 🍮]");
 | 
			
		||||
const preview_x2 = ref('$[x2 🍮]');
 | 
			
		||||
const preview_x3 = ref('$[x3 🍮]');
 | 
			
		||||
const preview_x4 = ref('$[x4 🍮]');
 | 
			
		||||
const preview_blur = ref(`$[blur ${i18n.ts._mfm.dummy}]`);
 | 
			
		||||
const preview_rainbow = ref(
 | 
			
		||||
	"$[rainbow 🍮] $[rainbow.speed=3s 🍮] $[rainbow.delay=3s 🍮] $[rainbow.loop=3 🍮]",
 | 
			
		||||
	'$[rainbow 🍮] $[rainbow.speed=3s 🍮] $[rainbow.delay=3s 🍮] $[rainbow.loop=3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_sparkle = ref("$[sparkle 🍮]");
 | 
			
		||||
const preview_sparkle = ref('$[sparkle 🍮]');
 | 
			
		||||
const preview_rotate = ref(
 | 
			
		||||
	"$[rotate 🍮]\n$[rotate.deg=45 🍮]\n$[rotate.x,deg=45 Hello, world!]",
 | 
			
		||||
	'$[rotate 🍮]\n$[rotate.deg=45 🍮]\n$[rotate.x,deg=45 Hello, world!]',
 | 
			
		||||
);
 | 
			
		||||
const preview_position = ref("$[position.y=-1 🍮]\n$[position.x=-1 🍮]");
 | 
			
		||||
const preview_position = ref('$[position.y=-1 🍮]\n$[position.x=-1 🍮]');
 | 
			
		||||
const preview_followmouse = ref('$[followmouse.x 🍮]\n$[followmouse.x,y,rotateByVelocity,speed=0.4 🍮]');
 | 
			
		||||
const preview_scale = ref(
 | 
			
		||||
	"$[scale.x=1.3 🍮]\n$[scale.x=1.5,y=3 🍮]\n$[scale.y=0.3 🍮]",
 | 
			
		||||
	'$[scale.x=1.3 🍮]\n$[scale.x=1.5,y=3 🍮]\n$[scale.y=0.3 🍮]',
 | 
			
		||||
);
 | 
			
		||||
const preview_fg = ref("$[fg.color=eb6f92 Text color]");
 | 
			
		||||
const preview_bg = ref("$[bg.color=31748f Background color]");
 | 
			
		||||
const preview_fg = ref('$[fg.color=eb6f92 Text color]');
 | 
			
		||||
const preview_bg = ref('$[bg.color=31748f Background color]');
 | 
			
		||||
const preview_plain = ref(
 | 
			
		||||
	"<plain>**bold** @mention #hashtag `code` $[x2 🍮]</plain>",
 | 
			
		||||
	'<plain>**bold** @mention #hashtag `code` $[x2 🍮]</plain>',
 | 
			
		||||
);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
import { VNode, h, defineAsyncComponent, SetupContext } from 'vue';
 | 
			
		||||
import * as mfm from '@transfem-org/sfm-js';
 | 
			
		||||
import * as Misskey from 'misskey-js';
 | 
			
		||||
import CkFollowMouse from '../CkFollowMouse.vue';
 | 
			
		||||
import MkUrl from '@/components/global/MkUrl.vue';
 | 
			
		||||
import MkTime from '@/components/global/MkTime.vue';
 | 
			
		||||
import MkLink from '@/components/MkLink.vue';
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +233,28 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
 | 
			
		|||
						style = `transform: rotate(${degrees}deg); transform-origin: center center;`;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					case 'followmouse': {
 | 
			
		||||
						// Make sure advanced MFM is on and that reduced motion is off
 | 
			
		||||
						if (!useAnim) {
 | 
			
		||||
							style = '';
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						let x = (!!token.props.args.x);
 | 
			
		||||
						let y = (!!token.props.args.y);
 | 
			
		||||
 | 
			
		||||
						if (!x && !y) {
 | 
			
		||||
							x = true;
 | 
			
		||||
							y = true;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						return h(CkFollowMouse, {
 | 
			
		||||
							x: x,
 | 
			
		||||
							y: y,
 | 
			
		||||
							speed: validTime(token.props.args.speed) ?? '0.1s',
 | 
			
		||||
							rotateByVelocity: !!token.props.args.rotateByVelocity,
 | 
			
		||||
						}, genEl(token.children, scale));
 | 
			
		||||
					}
 | 
			
		||||
					case 'position': {
 | 
			
		||||
						if (!defaultStore.state.advancedMfm) break;
 | 
			
		||||
						const x = safeParseFloat(token.props.args.x) ?? 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -162,7 +162,7 @@ export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://launcher.moe/error.png';
 | 
			
		|||
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://launcher.moe/missingpage.webp';
 | 
			
		||||
export const DEFAULT_INFO_IMAGE_URL = 'https://launcher.moe/nothinghere.png';
 | 
			
		||||
 | 
			
		||||
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime'];
 | 
			
		||||
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime', 'followmouse'];
 | 
			
		||||
export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
 | 
			
		||||
	tada: ['speed=', 'delay='],
 | 
			
		||||
	jelly: ['speed=', 'delay='],
 | 
			
		||||
| 
						 | 
				
			
			@ -186,4 +186,5 @@ export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
 | 
			
		|||
	rotate: ['deg='],
 | 
			
		||||
	ruby: [],
 | 
			
		||||
	unixtime: [],
 | 
			
		||||
	followmouse: ['x', 'y', 'rotateByVelocity', 'speed='],
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue