* perf(#10923): unwind css module class name
* perf(#10923): support multiple components
* refactor: clean up
* refactor(#10923): avoid `useCssModule()`
* fix(#10923): allow direct literal class name
* fix(#10923): avoid computed class name
* fix(#10923): allow literal keys
* fix(#10923): typo
* fix(#10923): invalid class names
* chore: test
* revert: test
This reverts commit 5c7ef366ec
.
* fix(#10923): hidden tale
* perf(#10923): also unwind scoped css contained components
* perf(#10923): `normalizeClass` AOT compilation
---------
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:

committed by
GitHub

parent
146e89edd0
commit
337dd97b49
@@ -3,7 +3,14 @@
|
||||
<div v-if="achievements" :class="$style.root">
|
||||
<div v-for="achievement in achievements" :key="achievement" :class="$style.achievement" class="_panel">
|
||||
<div :class="$style.icon">
|
||||
<div :class="[$style.iconFrame, $style['iconFrame_' + ACHIEVEMENT_BADGES[achievement.name].frame]]">
|
||||
<div
|
||||
:class="[$style.iconFrame, {
|
||||
[$style.iconFrame_bronze]: ACHIEVEMENT_BADGES[achievement.name].frame === 'bronze',
|
||||
[$style.iconFrame_silver]: ACHIEVEMENT_BADGES[achievement.name].frame === 'silver',
|
||||
[$style.iconFrame_gold]: ACHIEVEMENT_BADGES[achievement.name].frame === 'gold',
|
||||
[$style.iconFrame_platinum]: ACHIEVEMENT_BADGES[achievement.name].frame === 'platinum',
|
||||
}]"
|
||||
>
|
||||
<div :class="[$style.iconInner]" :style="{ background: ACHIEVEMENT_BADGES[achievement.name].bg }">
|
||||
<img :class="$style.iconImg" :src="ACHIEVEMENT_BADGES[achievement.name].img">
|
||||
</div>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</li>
|
||||
<li tabindex="-1" :class="$style.item" @click="chooseUser()" @keydown="onKeydown">{{ i18n.ts.selectUser }}</li>
|
||||
</ol>
|
||||
<ol v-else-if="hashtags.length > 0" ref="suggests" :class="[$style.list, $style.hashtags]">
|
||||
<ol v-else-if="hashtags.length > 0" ref="suggests" :class="$style.list">
|
||||
<li v-for="hashtag in hashtags" tabindex="-1" :class="$style.item" @click="complete(type, hashtag)" @keydown="onKeydown">
|
||||
<span class="name">{{ hashtag }}</span>
|
||||
</li>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
@click="emit('click', $event)"
|
||||
@mousedown="onMousedown"
|
||||
>
|
||||
<div ref="ripples" :class="$style.ripples"></div>
|
||||
<div ref="ripples" :class="$style.ripples" :data-children-class="$style.ripple"></div>
|
||||
<div :class="$style.content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
:to="to"
|
||||
@mousedown="onMousedown"
|
||||
>
|
||||
<div ref="ripples" :class="$style.ripples"></div>
|
||||
<div ref="ripples" :class="$style.ripples" :data-children-class="$style.ripple"></div>
|
||||
<div :class="$style.content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
@@ -26,9 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, useCssModule } from 'vue';
|
||||
|
||||
const $style = useCssModule();
|
||||
import { nextTick, onMounted } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
type?: 'button' | 'submit' | 'reset';
|
||||
@@ -81,7 +79,7 @@ function onMousedown(evt: MouseEvent): void {
|
||||
const rect = target.getBoundingClientRect();
|
||||
|
||||
const ripple = document.createElement('div');
|
||||
ripple.classList.add($style.ripple);
|
||||
ripple.classList.add(ripples!.dataset.childrenClass!);
|
||||
ripple.style.top = (evt.clientY - rect.top - 1).toString() + 'px';
|
||||
ripple.style.left = (evt.clientX - rect.left - 1).toString() + 'px';
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<div v-if="game.ready" :class="$style.game">
|
||||
<div :class="$style.cps" class="">{{ number(cps) }}cps</div>
|
||||
<div :class="$style.count" class=""><i class="ti ti-cookie" style="font-size: 70%;"></i> {{ number(cookies) }}</div>
|
||||
<button v-click-anime class="_button" :class="$style.button" @click="onClick">
|
||||
<button v-click-anime class="_button" @click="onClick">
|
||||
<img src="/client-assets/cookie.png" :class="$style.img">
|
||||
</button>
|
||||
</div>
|
||||
@@ -84,10 +84,6 @@ onUnmounted(() => {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.button {
|
||||
|
||||
}
|
||||
|
||||
.img {
|
||||
max-width: 90px;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="rootEl" class="_panel" :class="[$style.root, { [$style.naked]: naked, [$style.thin]: thin, [$style.hideHeader]: !showHeader, [$style.scrollable]: scrollable, [$style.closed]: !showBody }]">
|
||||
<div ref="rootEl" class="_panel" :class="[$style.root, { [$style.naked]: naked, [$style.thin]: thin, [$style.scrollable]: scrollable }]">
|
||||
<header v-if="showHeader" ref="headerEl" :class="$style.header">
|
||||
<div :class="$style.title">
|
||||
<span :class="$style.titleIcon"><slot name="icon"></slot></span>
|
||||
|
@@ -36,7 +36,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
setup(props, { slots, expose }) {
|
||||
const $style = useCssModule();
|
||||
const $style = useCssModule(); // カスタムレンダラなので使っても大丈夫
|
||||
function getDateText(time: string) {
|
||||
const date = new Date(time).getDate();
|
||||
const month = new Date(time).getMonth() + 1;
|
||||
|
@@ -4,7 +4,15 @@
|
||||
<div v-if="icon" :class="$style.icon">
|
||||
<i :class="icon"></i>
|
||||
</div>
|
||||
<div v-else-if="!input && !select" :class="[$style.icon, $style['type_' + type]]">
|
||||
<div
|
||||
v-else-if="!input && !select"
|
||||
:class="[$style.icon, {
|
||||
[$style.type_success]: type === 'success',
|
||||
[$style.type_error]: type === 'error',
|
||||
[$style.type_warning]: type === 'warning',
|
||||
[$style.type_info]: type === 'info',
|
||||
}]"
|
||||
>
|
||||
<i v-if="type === 'success'" :class="$style.iconInner" class="ti ti-check"></i>
|
||||
<i v-else-if="type === 'error'" :class="$style.iconInner" class="ti ti-circle-x"></i>
|
||||
<i v-else-if="type === 'warning'" :class="$style.iconInner" class="ti ti-alert-triangle"></i>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<div :class="[$style.header, { [$style.opened]: opened }]" class="_button" role="button" data-cy-folder-header @click="toggle">
|
||||
<div :class="$style.headerIcon"><slot name="icon"></slot></div>
|
||||
<div :class="$style.headerText">
|
||||
<div :class="$style.headerTextMain">
|
||||
<div>
|
||||
<MkCondensedLine :minScale="2 / 3"><slot name="label"></slot></MkCondensedLine>
|
||||
</div>
|
||||
<div :class="$style.headerTextSub">
|
||||
@@ -185,10 +185,6 @@ onMounted(() => {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.headerTextMain {
|
||||
|
||||
}
|
||||
|
||||
.headerTextSub {
|
||||
color: var(--fgTransparentWeak);
|
||||
font-size: .85em;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<TransitionGroup
|
||||
:duration="defaultStore.state.animation && props.transition?.duration || undefined"
|
||||
:enterActiveClass="defaultStore.state.animation && props.transition?.enterActiveClass || undefined"
|
||||
:leaveActiveClass="defaultStore.state.animation && (props.transition?.leaveActiveClass ?? $style['transition_leaveActive']) || undefined"
|
||||
:leaveActiveClass="defaultStore.state.animation && (props.transition?.leaveActiveClass ?? $style.transition_leaveActive) || undefined"
|
||||
:enterFromClass="defaultStore.state.animation && props.transition?.enterFromClass || undefined"
|
||||
:leaveToClass="defaultStore.state.animation && props.transition?.leaveToClass || undefined"
|
||||
:enterToClass="defaultStore.state.animation && props.transition?.enterToClass || undefined"
|
||||
@@ -42,11 +42,10 @@ const workerPromise = new Promise<WorkerMultiDispatch | null>(resolve => {
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, onMounted, onUnmounted, shallowRef, useCssModule, watch } from 'vue';
|
||||
import { computed, nextTick, onMounted, onUnmounted, shallowRef, watch } from 'vue';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { render } from 'buraha';
|
||||
import { defaultStore } from '@/store';
|
||||
const $style = useCssModule();
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
transition?: {
|
||||
|
@@ -6,8 +6,11 @@
|
||||
ref="gallery"
|
||||
:class="[
|
||||
$style.medias,
|
||||
count <= 4 ? $style['n' + count] : $style.nMany,
|
||||
$style[`n1${defaultStore.reactiveState.mediaListWithOneImageAppearance.value}`]
|
||||
count === 1 ? [$style.n1, {
|
||||
[$style.n116_9]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '16_9',
|
||||
[$style.n11_1]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '1_1',
|
||||
[$style.n12_3]: defaultStore.reactiveState.mediaListWithOneImageAppearance.value === '2_3',
|
||||
}] : count === 2 ? $style.n2 : count === 3 ? $style.n3 : count === 4 ? $style.n4 : $style.nMany,
|
||||
]"
|
||||
>
|
||||
<template v-for="media in mediaList.filter(media => previewable(media))">
|
||||
@@ -20,7 +23,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, useCssModule, watch, shallowRef } from 'vue';
|
||||
import { onMounted, watch, shallowRef } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import PhotoSwipeLightbox from 'photoswipe/lightbox';
|
||||
import PhotoSwipe from 'photoswipe';
|
||||
@@ -37,8 +40,6 @@ const props = defineProps<{
|
||||
raw?: boolean;
|
||||
}>();
|
||||
|
||||
const $style = useCssModule();
|
||||
|
||||
const gallery = shallowRef<HTMLDivElement>();
|
||||
const pswpZIndex = os.claimZIndex('middle');
|
||||
document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
|
||||
@@ -96,7 +97,7 @@ onMounted(() => {
|
||||
return item;
|
||||
}),
|
||||
gallery: gallery.value,
|
||||
mainClass: $style.pswp,
|
||||
mainClass: 'pswp',
|
||||
children: '.image',
|
||||
thumbSelector: '.image',
|
||||
loop: false,
|
||||
@@ -268,7 +269,7 @@ const previewable = (file: misskey.entities.DriveFile): boolean => {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.pswp {
|
||||
:global(.pswp) {
|
||||
--pswp-root-z-index: var(--mk-pswp-root-z-index, 2000700) !important;
|
||||
--pswp-bg: var(--modalBg) !important;
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<MkA v-user-preview="canonical" :class="[$style.root, { [$style.isMe]: isMe }]" :to="url" :style="{ background: bgCss }">
|
||||
<img :class="$style.icon" :src="`/avatar/@${username}@${host}`" alt="">
|
||||
<span>
|
||||
<span :class="$style.username">@{{ username }}</span>
|
||||
<span>@{{ username }}</span>
|
||||
<span v-if="(host != localHost) || defaultStore.state.showFullAcct" :class="$style.host">@{{ toUnicode(host) }}</span>
|
||||
</span>
|
||||
</MkA>
|
||||
|
@@ -49,7 +49,7 @@
|
||||
<span>{{ i18n.ts.none }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="childMenu" :class="$style.child">
|
||||
<div v-if="childMenu">
|
||||
<XChild ref="child" :items="childMenu" :targetElement="childTarget" :rootElement="itemsEl" showing @actioned="childActioned"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,10 +1,30 @@
|
||||
<template>
|
||||
<Transition
|
||||
:name="transitionName"
|
||||
:enterActiveClass="$style['transition_' + transitionName + '_enterActive']"
|
||||
:leaveActiveClass="$style['transition_' + transitionName + '_leaveActive']"
|
||||
:enterFromClass="$style['transition_' + transitionName + '_enterFrom']"
|
||||
:leaveToClass="$style['transition_' + transitionName + '_leaveTo']"
|
||||
:enterActiveClass="normalizeClass({
|
||||
[$style.transition_modalDrawer_enterActive]: transitionName === 'modal-drawer',
|
||||
[$style.transition_modalPopup_enterActive]: transitionName === 'modal-popup',
|
||||
[$style.transition_modal_enterActive]: transitionName === 'modal',
|
||||
[$style.transition_send_enterActive]: transitionName === 'send',
|
||||
})"
|
||||
:leaveActiveClass="normalizeClass({
|
||||
[$style.transition_modalDrawer_leaveActive]: transitionName === 'modal-drawer',
|
||||
[$style.transition_modalPopup_leaveActive]: transitionName === 'modal-popup',
|
||||
[$style.transition_modal_leaveActive]: transitionName === 'modal',
|
||||
[$style.transition_send_leaveActive]: transitionName === 'send',
|
||||
})"
|
||||
:enterFromClass="normalizeClass({
|
||||
[$style.transition_modalDrawer_enterFrom]: transitionName === 'modal-drawer',
|
||||
[$style.transition_modalPopup_enterFrom]: transitionName === 'modal-popup',
|
||||
[$style.transition_modal_enterFrom]: transitionName === 'modal',
|
||||
[$style.transition_send_enterFrom]: transitionName === 'send',
|
||||
})"
|
||||
:leaveToClass="normalizeClass({
|
||||
[$style.transition_modalDrawer_leaveTo]: transitionName === 'modal-drawer',
|
||||
[$style.transition_modalPopup_leaveTo]: transitionName === 'modal-popup',
|
||||
[$style.transition_modal_leaveTo]: transitionName === 'modal',
|
||||
[$style.transition_send_leaveTo]: transitionName === 'send',
|
||||
})"
|
||||
:duration="transitionDuration" appear @afterLeave="emit('closed')" @enter="emit('opening')" @afterEnter="onOpened"
|
||||
>
|
||||
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" :class="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog', [$style.popup]: type === 'popup' }]" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
|
||||
@@ -17,7 +37,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, watch, provide, onUnmounted } from 'vue';
|
||||
import { nextTick, normalizeClass, onMounted, onUnmounted, provide, watch } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import { defaultStore } from '@/store';
|
||||
@@ -345,8 +365,8 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
.transition_modal-popup_enterActive,
|
||||
.transition_modal-popup_leaveActive {
|
||||
.transition_modalPopup_enterActive,
|
||||
.transition_modalPopup_leaveActive {
|
||||
> .bg {
|
||||
transition: opacity 0.1s !important;
|
||||
}
|
||||
@@ -356,8 +376,8 @@ defineExpose({
|
||||
transition: opacity 0.1s cubic-bezier(0, 0, 0.2, 1), transform 0.1s cubic-bezier(0, 0, 0.2, 1) !important;
|
||||
}
|
||||
}
|
||||
.transition_modal-popup_enterFrom,
|
||||
.transition_modal-popup_leaveTo {
|
||||
.transition_modalPopup_enterFrom,
|
||||
.transition_modalPopup_leaveTo {
|
||||
> .bg {
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -370,7 +390,7 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
.transition_modal-drawer_enterActive {
|
||||
.transition_modalDrawer_enterActive {
|
||||
> .bg {
|
||||
transition: opacity 0.2s !important;
|
||||
}
|
||||
@@ -379,7 +399,7 @@ defineExpose({
|
||||
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
||||
}
|
||||
}
|
||||
.transition_modal-drawer_leaveActive {
|
||||
.transition_modalDrawer_leaveActive {
|
||||
> .bg {
|
||||
transition: opacity 0.2s !important;
|
||||
}
|
||||
@@ -388,8 +408,8 @@ defineExpose({
|
||||
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
||||
}
|
||||
}
|
||||
.transition_modal-drawer_enterFrom,
|
||||
.transition_modal-drawer_leaveTo {
|
||||
.transition_modalDrawer_enterFrom,
|
||||
.transition_modalDrawer_leaveTo {
|
||||
> .bg {
|
||||
opacity: 0;
|
||||
}
|
||||
|
@@ -44,8 +44,8 @@
|
||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||
<MkAvatar :class="$style.avatar" :user="appearNote.user" link preview/>
|
||||
<div :class="$style.main">
|
||||
<MkNoteHeader :class="$style.header" :note="appearNote" :mini="true"/>
|
||||
<MkInstanceTicker v-if="showTicker" :class="$style.ticker" :instance="appearNote.user.instance"/>
|
||||
<MkNoteHeader :note="appearNote" :mini="true"/>
|
||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||
<div style="container-type: inline-size;">
|
||||
<p v-if="appearNote.cw != null" :class="$style.cw">
|
||||
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :i="$i"/>
|
||||
@@ -58,13 +58,13 @@
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
<div v-if="translating || translation" :class="$style.translation">
|
||||
<MkLoading v-if="translating" mini/>
|
||||
<div v-else :class="$style.translated">
|
||||
<div v-else>
|
||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appearNote.files.length > 0" :class="$style.files">
|
||||
<div v-if="appearNote.files.length > 0">
|
||||
<MkMediaList :mediaList="appearNote.files"/>
|
||||
</div>
|
||||
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
|
||||
|
@@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div :class="$style.noteHeaderUsername"><MkAcct :user="appearNote.user"/></div>
|
||||
<MkInstanceTicker v-if="showTicker" :class="$style.ticker" :instance="appearNote.user.instance"/>
|
||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||
</div>
|
||||
</header>
|
||||
<div :class="$style.noteContent">
|
||||
@@ -72,7 +72,7 @@
|
||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appearNote.files.length > 0" :class="$style.files">
|
||||
<div v-if="appearNote.files.length > 0">
|
||||
<MkMediaList :mediaList="appearNote.files"/>
|
||||
</div>
|
||||
<MkPoll v-if="appearNote.poll" ref="pollViewer" :note="appearNote" :class="$style.poll"/>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<MkUserName :user="$i" :nowrap="true"/>
|
||||
</div>
|
||||
<div>
|
||||
<div :class="$style.content">
|
||||
<div>
|
||||
<Mfm :text="text.trim()" :author="$i" :i="$i"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -5,7 +5,19 @@
|
||||
<MkAvatar v-else-if="notification.type === 'achievementEarned'" :class="$style.icon" :user="$i" link preview/>
|
||||
<MkAvatar v-else-if="notification.user" :class="$style.icon" :user="notification.user" link preview/>
|
||||
<img v-else-if="notification.icon" :class="$style.icon" :src="notification.icon" alt=""/>
|
||||
<div :class="[$style.subIcon, $style['t_' + notification.type]]">
|
||||
<div
|
||||
:class="[$style.subIcon, {
|
||||
[$style.t_follow]: notification.type === 'follow',
|
||||
[$style.t_followRequestAccepted]: notification.type === 'followRequestAccepted',
|
||||
[$style.t_receiveFollowRequest]: notification.type === 'receiveFollowRequest',
|
||||
[$style.t_renote]: notification.type === 'renote',
|
||||
[$style.t_reply]: notification.type === 'reply',
|
||||
[$style.t_mention]: notification.type === 'mention',
|
||||
[$style.t_quote]: notification.type === 'quote',
|
||||
[$style.t_pollEnded]: notification.type === 'pollEnded',
|
||||
[$style.t_achievementEarned]: notification.type === 'achievementEarned',
|
||||
}]"
|
||||
>
|
||||
<i v-if="notification.type === 'follow'" class="ti ti-plus"></i>
|
||||
<i v-else-if="notification.type === 'receiveFollowRequest'" class="ti ti-clock"></i>
|
||||
<i v-else-if="notification.type === 'followRequestAccepted'" class="ti ti-check"></i>
|
||||
@@ -34,7 +46,7 @@
|
||||
<span v-else>{{ notification.header }}</span>
|
||||
<MkTime v-if="withTime" :time="notification.createdAt" :class="$style.headerTime"/>
|
||||
</header>
|
||||
<div :class="$style.content">
|
||||
<div>
|
||||
<MkA v-if="notification.type === 'reaction'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
|
||||
<i class="ti ti-quote" :class="$style.quote"></i>
|
||||
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :author="notification.note.user"/>
|
||||
@@ -243,9 +255,6 @@ useTooltip(reactionRef, (showing) => {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.content {
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="{ [$style.done]: closed || isVoted }">
|
||||
<ul :class="$style.choices">
|
||||
<li v-for="(choice, i) in note.poll.choices" :key="i" :class="[$style.choice, { [$style.voted]: choice.voted }]" @click="vote(i)">
|
||||
<li v-for="(choice, i) in note.poll.choices" :key="i" :class="$style.choice" @click="vote(i)">
|
||||
<div :class="$style.bg" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div>
|
||||
<span :class="$style.fg">
|
||||
<template v-if="choice.isVoted"><i class="ti ti-check" style="margin-right: 4px; color: var(--accent);"></i></template>
|
||||
|
@@ -27,16 +27,16 @@
|
||||
<span :class="$style.headerRightButtonText">{{ channel.name }}</span>
|
||||
</button>
|
||||
</template>
|
||||
<button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, $style.localOnly, { [$style.danger]: localOnly }]" :disabled="channel != null || visibility === 'specified'" @click="toggleLocalOnly">
|
||||
<button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, { [$style.danger]: localOnly }]" :disabled="channel != null || visibility === 'specified'" @click="toggleLocalOnly">
|
||||
<span v-if="!localOnly"><i class="ti ti-rocket"></i></span>
|
||||
<span v-else><i class="ti ti-rocket-off"></i></span>
|
||||
</button>
|
||||
<button v-click-anime v-tooltip="i18n.ts.reactionAcceptance" class="_button" :class="[$style.headerRightItem, $style.reactionAcceptance, { [$style.danger]: reactionAcceptance === 'likeOnly' }]" @click="toggleReactionAcceptance">
|
||||
<button v-click-anime v-tooltip="i18n.ts.reactionAcceptance" class="_button" :class="[$style.headerRightItem, { [$style.danger]: reactionAcceptance === 'likeOnly' }]" @click="toggleReactionAcceptance">
|
||||
<span v-if="reactionAcceptance === 'likeOnly'"><i class="ti ti-heart"></i></span>
|
||||
<span v-else-if="reactionAcceptance === 'likeOnlyForRemote'"><i class="ti ti-heart-plus"></i></span>
|
||||
<span v-else><i class="ti ti-icons"></i></span>
|
||||
</button>
|
||||
<button v-click-anime class="_button" :class="[$style.submit, { [$style.submitPosting]: posting }]" :disabled="!canPost" data-cy-open-post-form-submit @click="post">
|
||||
<button v-click-anime class="_button" :class="$style.submit" :disabled="!canPost" data-cy-open-post-form-submit @click="post">
|
||||
<div :class="$style.submitInner">
|
||||
<template v-if="posted"></template>
|
||||
<template v-else-if="posting"><MkEllipsis/></template>
|
||||
@@ -66,7 +66,7 @@
|
||||
<div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div>
|
||||
</div>
|
||||
<input v-show="withHashtags" ref="hashtagsInputEl" v-model="hashtags" :class="$style.hashtags" :placeholder="i18n.ts.hashtags" list="hashtags">
|
||||
<XPostFormAttaches v-model="files" :class="$style.attaches" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/>
|
||||
<XPostFormAttaches v-model="files" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/>
|
||||
<MkPollEditor v-if="poll" v-model="poll" @destroyed="poll = null"/>
|
||||
<MkNotePreview v-if="showPreview" :class="$style.preview" :text="text"/>
|
||||
<div v-if="showingOptions" style="padding: 8px 16px;">
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :class="[$style.root, { [$style.collapsed]: collapsed }]">
|
||||
<div :class="$style.body">
|
||||
<div>
|
||||
<span v-if="note.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||
<span v-if="note.deletedAt" style="opacity: 0.5">({{ i18n.ts.deleted }})</span>
|
||||
<MkA v-if="note.replyId" :class="$style.reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||
@@ -76,10 +76,6 @@ const collapsed = $ref(
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
|
||||
}
|
||||
|
||||
.reply {
|
||||
margin-right: 6px;
|
||||
color: var(--accent);
|
||||
|
@@ -6,7 +6,7 @@
|
||||
ref="inputEl"
|
||||
v-model="v"
|
||||
v-adaptive-border
|
||||
:class="[$style.textarea, { [$style.code]: code, _monospace: code }]"
|
||||
:class="[$style.textarea, { _monospace: code }]"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
:readonly="readonly"
|
||||
|
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="tweetId && tweetExpanded">
|
||||
<div ref="twitter" :class="$style.twitter">
|
||||
<div ref="twitter">
|
||||
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${defaultStore.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
||||
</div>
|
||||
<div :class="$style.action">
|
||||
@@ -31,7 +31,7 @@
|
||||
</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else :class="$style.urlPreview">
|
||||
<div v-else>
|
||||
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
|
||||
<div v-if="thumbnail" :class="$style.thumbnail" :style="`background-image: url('${thumbnail}')`">
|
||||
</div>
|
||||
@@ -210,13 +210,6 @@ onUnmounted(() => {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.twitter {
|
||||
|
||||
}
|
||||
|
||||
.urlPreview {
|
||||
}
|
||||
|
||||
.link {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<div v-tooltip="text" :class="[$style.root, $style['status_' + user.onlineStatus]]"></div>
|
||||
<div
|
||||
v-tooltip="text"
|
||||
:class="[$style.root, {
|
||||
[$style.status_online]: user.onlineStatus === 'online',
|
||||
[$style.status_active]: user.onlineStatus === 'active',
|
||||
[$style.status_offline]: user.onlineStatus === 'offline',
|
||||
[$style.status_unknown]: user.onlineStatus === 'unknown',
|
||||
}]"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>{{ i18n.ts.selectUser }}</template>
|
||||
<div :class="$style.root">
|
||||
<div>
|
||||
<div :class="$style.form">
|
||||
<FormSplit :minWidth="170">
|
||||
<MkInput v-model="username" :autofocus="true" @update:modelValue="search">
|
||||
@@ -126,8 +126,6 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
}
|
||||
|
||||
.form {
|
||||
padding: 0 var(--root-margin);
|
||||
|
@@ -3,9 +3,9 @@
|
||||
<div :class="$style.root">
|
||||
<div v-for="u in users" :key="u.id" :class="$style.user">
|
||||
<MkAvatar :class="$style.avatar" :user="u"/>
|
||||
<MkUserName :class="$style.name" :user="u" :nowrap="true"/>
|
||||
<MkUserName :user="u" :nowrap="true"/>
|
||||
</div>
|
||||
<div v-if="users.length < count" :class="$style.omitted">+{{ count - users.length }}</div>
|
||||
<div v-if="users.length < count">+{{ count - users.length }}</div>
|
||||
</div>
|
||||
</MkTooltip>
|
||||
</template>
|
||||
@@ -43,14 +43,6 @@ const emit = defineEmits<{
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
|
||||
}
|
||||
|
||||
.omitted {
|
||||
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
@@ -39,7 +39,7 @@
|
||||
<MkTimeline src="local"/>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="[$style.activeUsersChart, $style.panel]">
|
||||
<div :class="$style.panel">
|
||||
<XActiveUsersChart/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -220,8 +220,4 @@ function exploreOtherServers() {
|
||||
height: 350px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.activeUsersChart {
|
||||
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="$style.root">
|
||||
<template v-if="edit">
|
||||
<header :class="$style['edit-header']">
|
||||
<header :class="$style.editHeader">
|
||||
<MkSelect v-model="widgetAdderSelected" style="margin-bottom: var(--margin)" data-cy-widget-select>
|
||||
<template #label>{{ i18n.ts.selectWidget }}</template>
|
||||
<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ i18n.t(`_widgets.${widget}`) }}</option>
|
||||
@@ -15,15 +15,15 @@
|
||||
handle=".handle"
|
||||
:animation="150"
|
||||
:group="{ name: 'SortableMkWidgets' }"
|
||||
:class="$style['edit-editing']"
|
||||
:class="$style.editEditing"
|
||||
@update:modelValue="v => emit('updateWidgets', v)"
|
||||
>
|
||||
<template #item="{element}">
|
||||
<div :class="[$style.widget, $style['customize-container']]" data-cy-customize-container>
|
||||
<button :class="$style['customize-container-config']" class="_button" @click.prevent.stop="configWidget(element.id)"><i class="ti ti-settings"></i></button>
|
||||
<button :class="$style['customize-container-remove']" data-cy-customize-container-remove class="_button" @click.prevent.stop="removeWidget(element)"><i class="ti ti-x"></i></button>
|
||||
<div :class="[$style.widget, $style.customizeContainer]" data-cy-customize-container>
|
||||
<button :class="$style.customizeContainerConfig" class="_button" @click.prevent.stop="configWidget(element.id)"><i class="ti ti-settings"></i></button>
|
||||
<button :class="$style.customizeContainerRemove" data-cy-customize-container-remove class="_button" @click.prevent.stop="removeWidget(element)"><i class="ti ti-x"></i></button>
|
||||
<div class="handle">
|
||||
<component :is="`widget-${element.name}`" :ref="el => widgetRefs[element.id] = el" class="widget" :class="$style['customize-container-handle-widget']" :widget="element" @updateProps="updateWidget(element.id, $event)"/>
|
||||
<component :is="`widget-${element.name}`" :ref="el => widgetRefs[element.id] = el" class="widget" :class="$style.customizeContainerHandleWidget" :widget="element" @updateProps="updateWidget(element.id, $event)"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -130,7 +130,7 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
|
||||
}
|
||||
|
||||
.edit {
|
||||
&-header {
|
||||
&Header {
|
||||
margin: 16px 0;
|
||||
|
||||
> * {
|
||||
@@ -139,17 +139,17 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
&-editing {
|
||||
&Editing {
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.customize-container {
|
||||
.customizeContainer {
|
||||
position: relative;
|
||||
cursor: move;
|
||||
|
||||
&-config,
|
||||
&-remove {
|
||||
&Config,
|
||||
&Remove {
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
top: 8px;
|
||||
@@ -160,17 +160,17 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&-config {
|
||||
&Config {
|
||||
right: 8px + 8px + 32px;
|
||||
}
|
||||
|
||||
&-remove {
|
||||
&Remove {
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
&-handle {
|
||||
&Handle {
|
||||
|
||||
&-widget {
|
||||
&Widget {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<span :class="$style.text"><slot></slot></span>
|
||||
<span :class="$style.suffix">
|
||||
<span :class="$style.suffixText"><slot name="suffix"></slot></span>
|
||||
<i class="ti ti-external-link" :class="$style.suffixIcon"></i>
|
||||
<i class="ti ti-external-link"></i>
|
||||
</span>
|
||||
</a>
|
||||
<MkA v-else :class="[$style.main, { [$style.active]: active }]" class="_button" :to="to" :behavior="behavior">
|
||||
@@ -13,7 +13,7 @@
|
||||
<span :class="$style.text"><slot></slot></span>
|
||||
<span :class="$style.suffix">
|
||||
<span :class="$style.suffixText"><slot name="suffix"></slot></span>
|
||||
<i class="ti ti-chevron-right" :class="$style.suffixIcon"></i>
|
||||
<i class="ti ti-chevron-right"></i>
|
||||
</span>
|
||||
</MkA>
|
||||
</div>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div :class="$style.label" @click="focus"><slot name="label"></slot></div>
|
||||
<div :class="$style.content">
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div :class="$style.caption"><slot name="caption"></slot></div>
|
||||
|
@@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div v-if="chosen && !shouldHide" :class="$style.root">
|
||||
<div v-if="!showMenu" :class="[$style.main, $style['form_' + chosen.place]]">
|
||||
<div
|
||||
v-if="!showMenu"
|
||||
:class="[$style.main, {
|
||||
[$style.form_square]: chosen.place === 'square',
|
||||
[$style.form_horizontal]: chosen.place === 'horizontal',
|
||||
[$style.form_horizontalBig]: chosen.place === 'horizontal-big',
|
||||
[$style.form_vertical]: chosen.place === 'vertical',
|
||||
}]"
|
||||
>
|
||||
<a :href="chosen.url" target="_blank" :class="$style.link">
|
||||
<img :src="chosen.imageUrl" :class="$style.img">
|
||||
<button class="_button" :class="$style.i" @click.prevent.stop="toggleMenu"><i :class="$style.iIcon" class="ti ti-info-circle"></i></button>
|
||||
@@ -122,7 +130,7 @@ function reduceFrequency(): void {
|
||||
}
|
||||
}
|
||||
|
||||
&.form_horizontal-big {
|
||||
&.form_horizontalBig {
|
||||
padding: 8px;
|
||||
|
||||
> .link,
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<template v-if="!self">
|
||||
<span :class="$style.schema">{{ schema }}//</span>
|
||||
<span :class="$style.hostname">{{ hostname }}</span>
|
||||
<span v-if="port != ''" :class="$style.port">:{{ port }}</span>
|
||||
<span v-if="port != ''">:{{ port }}</span>
|
||||
</template>
|
||||
<template v-if="pathname === '/' && self">
|
||||
<span :class="$style.self">{{ hostname }}</span>
|
||||
|
@@ -1,6 +1,15 @@
|
||||
<template>
|
||||
<section>
|
||||
<component :is="'h' + h" :class="h < 5 ? $style['h' + h] : null">{{ block.title }}</component>
|
||||
<component
|
||||
:is="'h' + h"
|
||||
:class="{
|
||||
'h2': h === 2,
|
||||
'h3': h === 3,
|
||||
'h4': h === 4,
|
||||
}"
|
||||
>
|
||||
{{ block.title }}
|
||||
</component>
|
||||
|
||||
<div class="_gaps">
|
||||
<XBlock v-for="child in block.children" :key="child.id" :page="page" :block="child" :h="h + 1"/>
|
||||
|
Reference in New Issue
Block a user