This commit is contained in:
nelle 2024-07-14 20:32:39 -06:00
parent 7b70d6cf94
commit a81d2cc778
9 changed files with 342 additions and 1 deletions

View file

@ -18,3 +18,4 @@ To apply a patch ``git am --keep-cr --signoff < {patch}``
- [Post Form Height](./patches/textarea.patch): Increases the post form height for usability
- [Remove Chats](./patches/remove-messaging.patch): Removes the pages and buttons referring to the local chats feature
- [Observers] Renames Followers/Following to Observers/Observing, as well as replaces the hand icon with an eye
- [New MFM](./newmfm/) Adds `followmouse`, `unixtime`, `ruby`, and `border` mfm tags from Sharkey/Misskey.

View file

@ -0,0 +1,76 @@
From bb131259350d68a6081fa5202477ba090d163363 Mon Sep 17 00:00:00 2001
From: limepotato <limepot@protonmail.ch>
Date: Sun, 14 Jul 2024 05:46:32 -0600
Subject: [PATCH 1/5] add border mfm
---
packages/client/src/components/mfm.ts | 20 ++++++++++++++++++++
packages/client/src/scripts/safe-parse.ts | 11 +++++++++++
2 files changed, 31 insertions(+)
create mode 100644 packages/client/src/scripts/safe-parse.ts
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
index a2c4fdcb7..32b72564b 100644
--- a/packages/client/src/components/mfm.ts
+++ b/packages/client/src/components/mfm.ts
@@ -14,6 +14,7 @@ import MkA from "@/components/global/MkA.vue";
import { host } from "@/config";
import { reducedMotion } from "@/scripts/reduced-motion";
import { defaultStore } from "@/store";
+import { safeParseFloat } from "@/scripts/safe-parse";
export default defineComponent({
props: {
@@ -70,6 +71,11 @@ export default defineComponent({
// : null
// }
+ const validColor = (c: unknown): string | null => {
+ if (typeof c !== 'string') return null;
+ return c.match(/^[0-9a-f]{3,6}$/i) ? c : null;
+ };
+
const genEl = (ast: mfm.MfmNode[]) =>
concat(
ast.map((token, index): VNode[] => {
@@ -300,6 +306,20 @@ export default defineComponent({
style = `background-color: #${color};`;
break;
}
+ case 'border': {
+ let color = validColor(token.props.args.color);
+ color = color ? `#${color}` : 'var(--accent)';
+ let b_style = token.props.args.style;
+ if (
+ typeof b_style !== 'string' ||
+ !['hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset']
+ .includes(b_style)
+ ) b_style = 'solid';
+ const width = safeParseFloat(token.props.args.width) ?? 1;
+ const radius = safeParseFloat(token.props.args.radius) ?? 0;
+ style = `border: ${width}px ${b_style} ${color}; border-radius: ${radius}px;${token.props.args.noclip ? '' : ' overflow: clip;'}`;
+ break;
+ }
case "small": {
return h(
"small",
diff --git a/packages/client/src/scripts/safe-parse.ts b/packages/client/src/scripts/safe-parse.ts
new file mode 100644
index 000000000..6bfcef6c3
--- /dev/null
+++ b/packages/client/src/scripts/safe-parse.ts
@@ -0,0 +1,11 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export function safeParseFloat(str: unknown): number | null {
+ if (typeof str !== 'string' || str === '') return null;
+ const num = parseFloat(str);
+ if (isNaN(num)) return null;
+ return num;
+}
--
2.45.2

View file

@ -0,0 +1,34 @@
From 54a84e11c19a4f90803c126d203e0e34fb202bd7 Mon Sep 17 00:00:00 2001
From: limepotato <limepot@protonmail.ch>
Date: Sun, 14 Jul 2024 06:01:33 -0600
Subject: [PATCH 2/5] ruby mfm
---
packages/client/src/components/mfm.ts | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
index 32b72564b..2beee156c 100644
--- a/packages/client/src/components/mfm.ts
+++ b/packages/client/src/components/mfm.ts
@@ -320,6 +320,17 @@ export default defineComponent({
style = `border: ${width}px ${b_style} ${color}; border-radius: ${radius}px;${token.props.args.noclip ? '' : ' overflow: clip;'}`;
break;
}
+ case 'ruby': {
+ if (token.children.length === 1) {
+ const child = token.children[0];
+ let text = child.type === 'text' ? child.props.text : '';
+ return h('ruby', {}, [text.split(' ')[0], h('rt', text.split(' ')[1])]);
+ } else {
+ const rt = token.children.at(-1)!;
+ let text = rt.type === 'text' ? rt.props.text : '';
+ return h('ruby', {}, [...genEl(token.children.slice(0, token.children.length - 1), scale), h('rt', text.trim())]);
+ }
+ }
case "small": {
return h(
"small",
--
2.45.2

View file

@ -0,0 +1,48 @@
From 846baf305be2d4547b91e6cfd6db5c64bc6ce793 Mon Sep 17 00:00:00 2001
From: limepotato <limepot@protonmail.ch>
Date: Sun, 14 Jul 2024 06:09:33 -0600
Subject: [PATCH 3/5] Unix Time MFM
---
packages/client/src/components/mfm.ts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
index 2beee156c..382b1b9e7 100644
--- a/packages/client/src/components/mfm.ts
+++ b/packages/client/src/components/mfm.ts
@@ -2,6 +2,7 @@ import { defineComponent, h } from "vue";
import * as mfm from "@transfem-org/sfm-js";
import type { VNode } from "vue";
import MkUrl from "@/components/global/MkUrl.vue";
+import MkTime from '@/components/global/MkTime.vue';
import MkLink from "@/components/MkLink.vue";
import MkMention from "@/components/MkMention.vue";
import MkEmoji from "@/components/global/MkEmoji.vue";
@@ -331,6 +332,23 @@ export default defineComponent({
return h('ruby', {}, [...genEl(token.children.slice(0, token.children.length - 1), scale), h('rt', text.trim())]);
}
}
+ case 'unixtime': {
+ const child = token.children[0];
+ const unixtime = parseInt(child.type === 'text' ? child.props.text : '');
+ return h('span', {
+ style: 'display: inline-block; font-size: 90%; border: solid 1px var(--divider); border-radius: var(--radius-ellipse); padding: 4px 10px 4px 6px;',
+ }, [
+ h('i', {
+ class: 'ph-clock ph-bold ph-lg',
+ style: 'margin-right: 0.25em;',
+ }),
+ h(MkTime, {
+ key: Math.random(),
+ time: unixtime * 1000,
+ mode: 'detail',
+ }),
+ ]);
+ }
case "small": {
return h(
"small",
--
2.45.2

View file

@ -0,0 +1,143 @@
From d41a81f60051c197ca98db912d706745edd002d7 Mon Sep 17 00:00:00 2001
From: limepotato <limepot@protonmail.ch>
Date: Sun, 14 Jul 2024 06:11:58 -0600
Subject: [PATCH 4/5] Follow Mouse MFM
---
.../client/src/components/CkFollowMouse.vue | 86 +++++++++++++++++++
packages/client/src/components/mfm.ts | 19 ++++
2 files changed, 105 insertions(+)
create mode 100644 packages/client/src/components/CkFollowMouse.vue
diff --git a/packages/client/src/components/CkFollowMouse.vue b/packages/client/src/components/CkFollowMouse.vue
new file mode 100644
index 000000000..ce7e3c79a
--- /dev/null
+++ b/packages/client/src/components/CkFollowMouse.vue
@@ -0,0 +1,86 @@
+<!--
+SPDX-FileCopyrightText: leah and other Cutiekey contributors
+SPDX-License-Identifier: AGPL-3.0-only
+-->
+
+<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>
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
index 382b1b9e7..25faf680b 100644
--- a/packages/client/src/components/mfm.ts
+++ b/packages/client/src/components/mfm.ts
@@ -1,6 +1,7 @@
import { defineComponent, h } from "vue";
import * as mfm from "@transfem-org/sfm-js";
import type { VNode } from "vue";
+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";
@@ -275,6 +276,24 @@ export default defineComponent({
style = `transform: ${rotate}(${degrees}deg); transform-origin: center center;`;
break;
}
+ case 'followmouse': {
+ // Make sure advanced MFM is on and that reduced motion is off
+
+ 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));
+ }
case "position": {
const x = parseFloat(token.props.args.x ?? "0");
const y = parseFloat(token.props.args.y ?? "0");
--
2.45.2

View file

@ -0,0 +1,31 @@
From bf99394851a6bc3e0bb8c5326ffed6a0be616593 Mon Sep 17 00:00:00 2001
From: limepotato <limepot@protonmail.ch>
Date: Sun, 14 Jul 2024 06:23:21 -0600
Subject: [PATCH 5/5] add mfm autocomplete
---
packages/client/src/scripts/mfm-tags.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/packages/client/src/scripts/mfm-tags.ts b/packages/client/src/scripts/mfm-tags.ts
index a3b51e483..2b15df815 100644
--- a/packages/client/src/scripts/mfm-tags.ts
+++ b/packages/client/src/scripts/mfm-tags.ts
@@ -11,10 +11,14 @@ export const MFM_TAGS = [
"x3",
"x4",
"scale",
+ "followmouse",
"position",
"crop",
"fg",
"bg",
+ "border",
+ "ruby",
+ "unixtime",
"font",
"blur",
"rainbow",
--
2.45.2

3
patches/newmfm/README.md Normal file
View file

@ -0,0 +1,3 @@
# NEW MFM
You first need to apply [This Patch](https://iceshrimp.dev/kopper/iceshrimp/commit/d36021406dfa01f551a3fa4ca62bd20a85b7717a) from kopper, then [download all patches](./newmfm.tar.gz) in this directory, and apply [newmfm.patch](./newmfm.patch).

View file

@ -0,0 +1,5 @@
0001-add-border-mfm.patch
0002-ruby-mfm.patch
0003-Unix-Time-MFM.patch
0004-Follow-Mouse-MFM.patch
0005-add-mfm-autocomplete.patch

Binary file not shown.