refactor(frontend): use composition api
This commit is contained in:
parent
3d4a90b08a
commit
0717afc312
8 changed files with 495 additions and 621 deletions
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="ssazuxis">
|
<div ref="el" class="ssazuxis">
|
||||||
<header class="_button" :style="{ background: bg }" @click="showBody = !showBody">
|
<header class="_button" :style="{ background: bg }" @click="showBody = !showBody">
|
||||||
<div class="title"><div><slot name="header"></slot></div></div>
|
<div class="title"><div><slot name="header"></slot></div></div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
@ -22,43 +22,55 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { onMounted, ref, shallowRef, watch } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { miLocalStorage } from '@/local-storage';
|
import { miLocalStorage } from '@/local-storage';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
|
|
||||||
const miLocalStoragePrefix = 'ui:folder:' as const;
|
const miLocalStoragePrefix = 'ui:folder:' as const;
|
||||||
|
|
||||||
export default defineComponent({
|
const props = withDefaults(defineProps<{
|
||||||
props: {
|
expanded?: boolean;
|
||||||
expanded: {
|
persistKey?: string;
|
||||||
type: Boolean,
|
}>(), {
|
||||||
required: false,
|
expanded: true,
|
||||||
default: true,
|
});
|
||||||
},
|
|
||||||
persistKey: {
|
const el = shallowRef<HTMLDivElement>();
|
||||||
type: String,
|
const bg = ref<string | null>(null);
|
||||||
required: false,
|
const showBody = ref((props.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${props.persistKey}`) === 't') : props.expanded);
|
||||||
default: null,
|
|
||||||
},
|
watch(showBody, () => {
|
||||||
},
|
if (props.persistKey) {
|
||||||
data() {
|
miLocalStorage.setItem(`${miLocalStoragePrefix}${props.persistKey}`, showBody.value ? 't' : 'f');
|
||||||
return {
|
|
||||||
defaultStore,
|
|
||||||
bg: null,
|
|
||||||
showBody: (this.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${this.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${this.persistKey}`) === 't') : this.expanded,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
showBody() {
|
|
||||||
if (this.persistKey) {
|
|
||||||
miLocalStorage.setItem(`${miLocalStoragePrefix}${this.persistKey}`, this.showBody ? 't' : 'f');
|
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
},
|
|
||||||
mounted() {
|
function enter(el: Element) {
|
||||||
function getParentBg(el: Element | null): string {
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
|
el.style.height = 0;
|
||||||
|
el.offsetHeight; // reflow
|
||||||
|
el.style.height = elementHeight + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterEnter(el: Element) {
|
||||||
|
el.style.height = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function leave(el: Element) {
|
||||||
|
const elementHeight = el.getBoundingClientRect().height;
|
||||||
|
el.style.height = elementHeight + 'px';
|
||||||
|
el.offsetHeight; // reflow
|
||||||
|
el.style.height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterLeave(el: Element) {
|
||||||
|
el.style.height = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
function getParentBg(el: HTMLElement | null): string {
|
||||||
if (el == null || el.tagName === 'BODY') return 'var(--bg)';
|
if (el == null || el.tagName === 'BODY') return 'var(--bg)';
|
||||||
const bg = el.style.background || el.style.backgroundColor;
|
const bg = el.style.background || el.style.backgroundColor;
|
||||||
if (bg) {
|
if (bg) {
|
||||||
|
@ -67,35 +79,10 @@ export default defineComponent({
|
||||||
return getParentBg(el.parentElement);
|
return getParentBg(el.parentElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const rawBg = getParentBg(this.$el);
|
const rawBg = getParentBg(el.value);
|
||||||
const bg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
const _bg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
||||||
bg.setAlpha(0.85);
|
_bg.setAlpha(0.85);
|
||||||
this.bg = bg.toRgbString();
|
bg.value = _bg.toRgbString();
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggleContent(show: boolean) {
|
|
||||||
this.showBody = show;
|
|
||||||
},
|
|
||||||
|
|
||||||
enter(el) {
|
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
|
||||||
el.style.height = 0;
|
|
||||||
el.offsetHeight; // reflow
|
|
||||||
el.style.height = elementHeight + 'px';
|
|
||||||
},
|
|
||||||
afterEnter(el) {
|
|
||||||
el.style.height = null;
|
|
||||||
},
|
|
||||||
leave(el) {
|
|
||||||
const elementHeight = el.getBoundingClientRect().height;
|
|
||||||
el.style.height = elementHeight + 'px';
|
|
||||||
el.offsetHeight; // reflow
|
|
||||||
el.style.height = 0;
|
|
||||||
},
|
|
||||||
afterLeave(el) {
|
|
||||||
el.style.height = null;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
</MkModalWindow>
|
</MkModalWindow>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { reactive, shallowRef } from 'vue';
|
||||||
import MkInput from './MkInput.vue';
|
import MkInput from './MkInput.vue';
|
||||||
import MkTextarea from './MkTextarea.vue';
|
import MkTextarea from './MkTextarea.vue';
|
||||||
import MkSwitch from './MkSwitch.vue';
|
import MkSwitch from './MkSwitch.vue';
|
||||||
|
@ -66,58 +66,36 @@ import MkRadios from './MkRadios.vue';
|
||||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
components: {
|
title: string;
|
||||||
MkModalWindow,
|
form: any;
|
||||||
MkInput,
|
}>();
|
||||||
MkTextarea,
|
|
||||||
MkSwitch,
|
|
||||||
MkSelect,
|
|
||||||
MkRange,
|
|
||||||
MkButton,
|
|
||||||
MkRadios,
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
const emit = defineEmits<{
|
||||||
title: {
|
(ev: 'done', v: {
|
||||||
type: String,
|
canceled?: boolean;
|
||||||
required: true,
|
result?: any;
|
||||||
},
|
}): void;
|
||||||
form: {
|
}>();
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
emits: ['done'],
|
const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
|
||||||
|
const values = reactive({});
|
||||||
|
|
||||||
data() {
|
for (const item in props.form) {
|
||||||
return {
|
values[item] = props.form[item].default ?? null;
|
||||||
values: {},
|
}
|
||||||
i18n,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
function ok() {
|
||||||
for (const item in this.form) {
|
emit('done', {
|
||||||
this.values[item] = this.form[item].default ?? null;
|
result: values,
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
ok() {
|
|
||||||
this.$emit('done', {
|
|
||||||
result: this.values,
|
|
||||||
});
|
});
|
||||||
this.$refs.dialog.close();
|
dialog.value.close();
|
||||||
},
|
}
|
||||||
|
|
||||||
cancel() {
|
function cancel() {
|
||||||
this.$emit('done', {
|
emit('done', {
|
||||||
canceled: true,
|
canceled: true,
|
||||||
});
|
});
|
||||||
this.$refs.dialog.close();
|
dialog.value.close();
|
||||||
},
|
}
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -28,54 +28,38 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import number from '@/filters/number';
|
import number from '@/filters/number';
|
||||||
|
import XValue from '@/components/MkObjectView.value.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
name: 'XValue',
|
value: any;
|
||||||
|
}>();
|
||||||
|
|
||||||
props: {
|
const collapsed = reactive({});
|
||||||
value: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(props) {
|
if (isObject(props.value)) {
|
||||||
const collapsed = reactive({});
|
|
||||||
|
|
||||||
if (isObject(props.value)) {
|
|
||||||
for (const key in props.value) {
|
for (const key in props.value) {
|
||||||
collapsed[key] = collapsable(props.value[key]);
|
collapsed[key] = collapsable(props.value[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isObject(v): boolean {
|
function isObject(v): boolean {
|
||||||
return typeof v === 'object' && !Array.isArray(v) && v !== null;
|
return typeof v === 'object' && !Array.isArray(v) && v !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isArray(v): boolean {
|
function isArray(v): boolean {
|
||||||
return Array.isArray(v);
|
return Array.isArray(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmpty(v): boolean {
|
function isEmpty(v): boolean {
|
||||||
return (isArray(v) && v.length === 0) || (isObject(v) && Object.keys(v).length === 0);
|
return (isArray(v) && v.length === 0) || (isObject(v) && Object.keys(v).length === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function collapsable(v): boolean {
|
function collapsable(v): boolean {
|
||||||
return (isObject(v) || isArray(v)) && !isEmpty(v);
|
return (isObject(v) || isArray(v)) && !isEmpty(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
number,
|
|
||||||
collapsed,
|
|
||||||
isObject,
|
|
||||||
isArray,
|
|
||||||
isEmpty,
|
|
||||||
collapsable,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -1,37 +1,27 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { VNode, defineComponent, h } from 'vue';
|
import { VNode, defineComponent, h, ref, watch } from 'vue';
|
||||||
import MkRadio from './MkRadio.vue';
|
import MkRadio from './MkRadio.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
|
||||||
MkRadio,
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
setup(props, context) {
|
||||||
return {
|
const value = ref(props.modelValue);
|
||||||
value: this.modelValue,
|
watch(value, () => {
|
||||||
};
|
context.emit('update:modelValue', value.value);
|
||||||
},
|
});
|
||||||
watch: {
|
if (!context.slots.default) return null;
|
||||||
value() {
|
let options = context.slots.default();
|
||||||
this.$emit('update:modelValue', this.value);
|
const label = context.slots.label && context.slots.label();
|
||||||
},
|
const caption = context.slots.caption && context.slots.caption();
|
||||||
},
|
|
||||||
render() {
|
|
||||||
console.log(this.$slots, this.$slots.label && this.$slots.label());
|
|
||||||
if (!this.$slots.default) return null;
|
|
||||||
let options = this.$slots.default();
|
|
||||||
const label = this.$slots.label && this.$slots.label();
|
|
||||||
const caption = this.$slots.caption && this.$slots.caption();
|
|
||||||
|
|
||||||
// なぜかFragmentになることがあるため
|
// なぜかFragmentになることがあるため
|
||||||
if (options.length === 1 && options[0].props == null) options = options[0].children as VNode[];
|
if (options.length === 1 && options[0].props == null) options = options[0].children as VNode[];
|
||||||
|
|
||||||
return h('div', {
|
return () => h('div', {
|
||||||
class: 'novjtcto',
|
class: 'novjtcto',
|
||||||
}, [
|
}, [
|
||||||
...(label ? [h('div', {
|
...(label ? [h('div', {
|
||||||
|
@ -42,8 +32,8 @@ export default defineComponent({
|
||||||
}, options.map(option => h(MkRadio, {
|
}, options.map(option => h(MkRadio, {
|
||||||
key: option.key,
|
key: option.key,
|
||||||
value: option.props?.value,
|
value: option.props?.value,
|
||||||
modelValue: this.value,
|
modelValue: value.value,
|
||||||
'onUpdate:modelValue': value => this.value = value,
|
'onUpdate:modelValue': _v => value.value = _v,
|
||||||
}, () => option.children)),
|
}, () => option.children)),
|
||||||
),
|
),
|
||||||
...(caption ? [h('div', {
|
...(caption ? [h('div', {
|
||||||
|
|
|
@ -7,17 +7,17 @@ export default defineComponent({
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render() {
|
setup(props, { emit, slots }) {
|
||||||
const options = this.$slots.default();
|
const options = slots.default();
|
||||||
|
|
||||||
return h('div', {
|
return () => h('div', {
|
||||||
class: 'pxhvhrfw',
|
class: 'pxhvhrfw',
|
||||||
}, options.map(option => withDirectives(h('button', {
|
}, options.map(option => withDirectives(h('button', {
|
||||||
class: ['_button', { active: this.modelValue === option.props.value }],
|
class: ['_button', { active: props.modelValue === option.props.value }],
|
||||||
key: option.key,
|
key: option.key,
|
||||||
disabled: this.modelValue === option.props.value,
|
disabled: props.modelValue === option.props.value,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
this.$emit('update:modelValue', option.props.value);
|
emit('update:modelValue', option.props.value);
|
||||||
},
|
},
|
||||||
}, option.children), [
|
}, option.children), [
|
||||||
[resolveDirective('click-anime')],
|
[resolveDirective('click-anime')],
|
||||||
|
|
|
@ -15,31 +15,22 @@
|
||||||
</Transition>
|
</Transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, PropType, ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
components: {
|
p: () => Promise<any>;
|
||||||
MkButton,
|
}>();
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
const pending = ref(true);
|
||||||
p: {
|
const resolved = ref(false);
|
||||||
type: Function as PropType<() => Promise<any>>,
|
const rejected = ref(false);
|
||||||
required: true,
|
const result = ref(null);
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(props, context) {
|
const process = () => {
|
||||||
const pending = ref(true);
|
|
||||||
const resolved = ref(false);
|
|
||||||
const rejected = ref(false);
|
|
||||||
const result = ref(null);
|
|
||||||
|
|
||||||
const process = () => {
|
|
||||||
if (props.p == null) {
|
if (props.p == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -56,29 +47,17 @@ export default defineComponent({
|
||||||
pending.value = false;
|
pending.value = false;
|
||||||
rejected.value = true;
|
rejected.value = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(() => props.p, () => {
|
watch(() => props.p, () => {
|
||||||
process();
|
process();
|
||||||
}, {
|
}, {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
|
||||||
|
|
||||||
const retry = () => {
|
|
||||||
process();
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
pending,
|
|
||||||
resolved,
|
|
||||||
rejected,
|
|
||||||
result,
|
|
||||||
retry,
|
|
||||||
defaultStore,
|
|
||||||
i18n,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const retry = () => {
|
||||||
|
process();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -1,24 +1,7 @@
|
||||||
import { h, defineComponent } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default function(props: { src: string; tag?: string; textTag?: string; }, { slots }) {
|
||||||
props: {
|
let str = props.src;
|
||||||
src: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
tag: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'span',
|
|
||||||
},
|
|
||||||
textTag: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
let str = this.src;
|
|
||||||
const parsed = [] as (string | { arg: string; })[];
|
const parsed = [] as (string | { arg: string; })[];
|
||||||
while (true) {
|
while (true) {
|
||||||
const nextBracketOpen = str.indexOf('{');
|
const nextBracketOpen = str.indexOf('{');
|
||||||
|
@ -37,6 +20,5 @@ export default defineComponent({
|
||||||
str = str.substr(nextBracketClose + 1);
|
str = str.substr(nextBracketClose + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return h(this.tag, parsed.map(x => typeof x === 'string' ? (this.textTag ? h(this.textTag, x) : x) : this.$slots[x.arg]()));
|
return h(props.tag ?? 'span', parsed.map(x => typeof x === 'string' ? (props.textTag ? h(props.textTag, x) : x) : slots[x.arg]()));
|
||||||
},
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { VNode, defineComponent, h } from 'vue';
|
import { VNode, h } from 'vue';
|
||||||
import * as mfm from 'mfm-js';
|
import * as mfm from 'mfm-js';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import MkUrl from '@/components/global/MkUrl.vue';
|
import MkUrl from '@/components/global/MkUrl.vue';
|
||||||
import MkLink from '@/components/MkLink.vue';
|
import MkLink from '@/components/MkLink.vue';
|
||||||
import MkMention from '@/components/MkMention.vue';
|
import MkMention from '@/components/MkMention.vue';
|
||||||
|
@ -21,46 +22,21 @@ border-left: solid 3px var(--fg);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
`.split('\n').join(' ');
|
`.split('\n').join(' ');
|
||||||
|
|
||||||
export default defineComponent({
|
export default function(props: {
|
||||||
props: {
|
text: string;
|
||||||
text: {
|
plain?: boolean;
|
||||||
type: String,
|
nowrap?: boolean;
|
||||||
required: true,
|
author?: Misskey.entities.UserLite;
|
||||||
},
|
i?: Misskey.entities.UserLite;
|
||||||
plain: {
|
isNote?: boolean;
|
||||||
type: Boolean,
|
emojiUrls?: string[];
|
||||||
default: false,
|
rootScale?: number;
|
||||||
},
|
}) {
|
||||||
nowrap: {
|
const isNote = props.isNote !== undefined ? props.isNote : true;
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
author: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
i: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
isNote: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
emojiUrls: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
rootScale: {
|
|
||||||
type: Number,
|
|
||||||
default: 1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
if (props.text == null || props.text === '') return;
|
||||||
if (this.text == null || this.text === '') return;
|
|
||||||
|
|
||||||
const ast = (this.plain ? mfm.parseSimple : mfm.parse)(this.text);
|
const ast = (props.plain ? mfm.parseSimple : mfm.parse)(props.text);
|
||||||
|
|
||||||
const validTime = (t: string | null | undefined) => {
|
const validTime = (t: string | null | undefined) => {
|
||||||
if (t == null) return null;
|
if (t == null) return null;
|
||||||
|
@ -79,7 +55,7 @@ export default defineComponent({
|
||||||
case 'text': {
|
case 'text': {
|
||||||
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
||||||
|
|
||||||
if (!this.plain) {
|
if (!props.plain) {
|
||||||
const res: (VNode | string)[] = [];
|
const res: (VNode | string)[] = [];
|
||||||
for (const t of text.split('\n')) {
|
for (const t of text.split('\n')) {
|
||||||
res.push(h('br'));
|
res.push(h('br'));
|
||||||
|
@ -280,7 +256,7 @@ export default defineComponent({
|
||||||
case 'mention': {
|
case 'mention': {
|
||||||
return [h(MkMention, {
|
return [h(MkMention, {
|
||||||
key: Math.random(),
|
key: Math.random(),
|
||||||
host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host,
|
host: (token.props.host == null && props.author && props.author.host != null ? props.author.host : token.props.host) || host,
|
||||||
username: token.props.username,
|
username: token.props.username,
|
||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
|
@ -288,7 +264,7 @@ export default defineComponent({
|
||||||
case 'hashtag': {
|
case 'hashtag': {
|
||||||
return [h(MkA, {
|
return [h(MkA, {
|
||||||
key: Math.random(),
|
key: Math.random(),
|
||||||
to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/user-tags/${encodeURIComponent(token.props.hashtag)}`,
|
to: isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/user-tags/${encodeURIComponent(token.props.hashtag)}`,
|
||||||
style: 'color:var(--hashtag);',
|
style: 'color:var(--hashtag);',
|
||||||
}, `#${token.props.hashtag}`)];
|
}, `#${token.props.hashtag}`)];
|
||||||
}
|
}
|
||||||
|
@ -310,7 +286,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'quote': {
|
case 'quote': {
|
||||||
if (!this.nowrap) {
|
if (!props.nowrap) {
|
||||||
return [h('div', {
|
return [h('div', {
|
||||||
style: QUOTE_STYLE,
|
style: QUOTE_STYLE,
|
||||||
}, genEl(token.children, scale))];
|
}, genEl(token.children, scale))];
|
||||||
|
@ -323,26 +299,26 @@ export default defineComponent({
|
||||||
|
|
||||||
case 'emojiCode': {
|
case 'emojiCode': {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (this.author?.host == null) {
|
if (props.author?.host == null) {
|
||||||
return [h(MkCustomEmoji, {
|
return [h(MkCustomEmoji, {
|
||||||
key: Math.random(),
|
key: Math.random(),
|
||||||
name: token.props.name,
|
name: token.props.name,
|
||||||
normal: this.plain,
|
normal: props.plain,
|
||||||
host: null,
|
host: null,
|
||||||
useOriginalSize: scale >= 2.5,
|
useOriginalSize: scale >= 2.5,
|
||||||
})];
|
})];
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (this.emojiUrls && (this.emojiUrls[token.props.name] == null)) {
|
if (props.emojiUrls && (props.emojiUrls[token.props.name] == null)) {
|
||||||
return [h('span', `:${token.props.name}:`)];
|
return [h('span', `:${token.props.name}:`)];
|
||||||
} else {
|
} else {
|
||||||
return [h(MkCustomEmoji, {
|
return [h(MkCustomEmoji, {
|
||||||
key: Math.random(),
|
key: Math.random(),
|
||||||
name: token.props.name,
|
name: token.props.name,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
url: this.emojiUrls ? this.emojiUrls[token.props.name] : null,
|
url: props.emojiUrls ? props.emojiUrls[token.props.name] : null,
|
||||||
normal: this.plain,
|
normal: props.plain,
|
||||||
host: this.author.host,
|
host: props.author.host,
|
||||||
useOriginalSize: scale >= 2.5,
|
useOriginalSize: scale >= 2.5,
|
||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
|
@ -384,7 +360,5 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}).flat(Infinity) as (VNode | string)[];
|
}).flat(Infinity) as (VNode | string)[];
|
||||||
|
|
||||||
// Parse ast to DOM
|
return h('span', genEl(ast, props.rootScale ?? 1));
|
||||||
return h('span', genEl(ast, this.rootScale));
|
}
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in a new issue