1
0
Fork 0
mirror of https://github.com/paricafe/misskey.git synced 2025-04-01 09:09:29 -05:00

enhance(frontend): improve ux for touch devices

This commit is contained in:
syuilo 2025-03-16 13:59:08 +09:00
parent 43153311c6
commit dca42fd6e6
30 changed files with 72 additions and 45 deletions

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div>
<div class="_fullinfo">
<img :src="notFoundImageUrl" class="_ghost"/>
<img :src="notFoundImageUrl" draggable="false"/>
<div>{{ i18n.ts.notFoundDescription }}</div>
</div>
</div>
@ -20,5 +20,5 @@ import { i18n } from '@/i18n.js';
const serverMetadata = inject(DI.serverMetadata)!;
const notFoundImageUrl = computed(() => serverMetadata?.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL);
const notFoundImageUrl = computed(() => serverMetadata.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL);
</script>

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.notFound }}</div>
</div>
</template>
@ -19,9 +19,9 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import type { Paging } from '@/components/MkPagination.vue';
import MkChannelPreview from '@/components/MkChannelPreview.vue';
import MkPagination from '@/components/MkPagination.vue';
import type { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';

View file

@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</div>
<div v-else class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</MkSpacer>

View file

@ -14,8 +14,34 @@ SPDX-License-Identifier: AGPL-3.0-only
:enterToClass="prefer.s.animation && props.transition?.enterToClass || undefined"
:leaveFromClass="prefer.s.animation && props.transition?.leaveFromClass || undefined"
>
<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"/>
<img v-show="!hide" key="img" ref="img" :height="imgHeight ?? undefined" :width="imgWidth ?? undefined" :class="$style.img" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async" tabindex="-1"/>
<canvas
v-show="hide"
key="canvas"
ref="canvas"
:class="$style.canvas"
:width="canvasWidth"
:height="canvasHeight"
:title="title ?? undefined"
draggable="false"
tabindex="-1"
style="-webkit-user-drag: none;"
/>
<img
v-show="!hide"
key="img"
ref="img"
:height="imgHeight ?? undefined"
:width="imgWidth ?? undefined"
:class="$style.img"
:src="src ?? undefined"
:title="title ?? undefined"
:alt="alt ?? undefined"
loading="eager"
decoding="async"
draggable="false"
tabindex="-1"
style="-webkit-user-drag: none;"
/>
</TransitionGroup>
</div>
</template>

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination ref="pagingComponent" :pagination="pagination" :disableAutoLoad="disableAutoLoad">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noNotes }}</div>
</div>
</template>
@ -33,10 +33,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { shallowRef } from 'vue';
import type { Paging } from '@/components/MkPagination.vue';
import MkNote from '@/components/MkNote.vue';
import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
import MkPagination from '@/components/MkPagination.vue';
import type { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination ref="pagingComponent" :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noNotifications }}</div>
</div>
</template>

View file

@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-else-if="empty" key="_empty_" class="empty">
<slot name="empty">
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</slot>

View file

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@click="toggleReaction()"
@contextmenu.prevent.stop="menu"
>
<MkReactionIcon :class="prefer.s.limitWidthOfReaction ? $style.limitWidth : ''" :reaction="reaction" :emojiUrl="note.reactionEmojis[reaction.substring(1, reaction.length - 1)]"/>
<MkReactionIcon style="pointer-events: none;" :class="prefer.s.limitWidthOfReaction ? $style.limitWidth : ''" :reaction="reaction" :emojiUrl="note.reactionEmojis[reaction.substring(1, reaction.length - 1)]"/>
<span :class="$style.count">{{ count }}</span>
</button>
</template>

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noUsers }}</div>
</div>
</template>
@ -21,9 +21,9 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import type { Paging } from '@/components/MkPagination.vue';
import MkUserInfo from '@/components/MkUserInfo.vue';
import MkPagination from '@/components/MkPagination.vue';
import type { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';

View file

@ -34,6 +34,8 @@ SPDX-License-Identifier: AGPL-3.0-only
translate: getDecorationOffset(decoration),
}"
alt=""
draggable="false"
style="-webkit-user-drag: none;"
>
</template>
</component>

View file

@ -9,6 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
src="/client-assets/dummy.png"
:title="alt"
draggable="false"
style="-webkit-user-drag: none;"
/>
<span v-else-if="errored">:{{ customEmojiName }}:</span>
<img
@ -18,6 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:alt="alt"
:title="alt"
decoding="async"
draggable="false"
@error="errored = true"
@load="errored = false"
@click="onClick"
@ -157,6 +160,7 @@ async function edit(name: string) {
.root {
height: 2em;
vertical-align: middle;
-webkit-user-drag: none;
transition: transform 0.2s ease;
&:hover {

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<Transition :name="prefer.s.animation ? '_transition_zoom' : ''" appear>
<div :class="$style.root">
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
<p :class="$style.text"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
<MkButton :class="$style.button" @click="() => emit('retry')">{{ i18n.ts.retry }}</MkButton>
</div>

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkLoading v-if="!loaded"/>
<Transition :name="prefer.s.animation ? '_transition_zoom' : ''" appear>
<div v-show="loaded" :class="$style.root">
<img :src="serverErrorImageUrl" class="_ghost" :class="$style.img"/>
<img :src="serverErrorImageUrl" draggable="false" :class="$style.img"/>
<div class="_gaps">
<div><b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.pageLoadError }}</b></div>
<div v-if="meta && (version === meta.version)">{{ i18n.ts.pageLoadErrorDescription }}</div>

View file

@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="usersPagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noUsers }}</div>
</div>
</template>

View file

@ -69,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
<div v-else class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>

View file

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noNotes }}</div>
</div>
</template>

View file

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination ref="paginationComponent" :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noFollowRequests }}</div>
</div>
</template>

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header><MkPageHeader/></template>
<MkSpacer v-if="!instance.disableRegistration || !($i && ($i.isAdmin || $i.policies.canInvite))" :contentMax="1200">
<div :class="$style.root">
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
<div :class="$style.text">
<i class="ti ti-alert-triangle"></i>
{{ i18n.ts.nothing }}
@ -36,12 +36,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, ref, shallowRef } from 'vue';
import * as Misskey from 'misskey-js';
import type { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import MkButton from '@/components/MkButton.vue';
import MkPagination from '@/components/MkPagination.vue';
import type { Paging } from '@/components/MkPagination.vue';
import MkInviteCode from '@/components/MkInviteCode.vue';
import { definePage } from '@/page.js';
import { serverErrorImageUrl, instance } from '@/instance.js';

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer v-if="error != null" :contentMax="1200">
<div :class="$style.root">
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
<p :class="$style.text">
<i class="ti ti-alert-triangle"></i>
{{ i18n.ts.nothing }}

View file

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>
<div v-if="antennas.length === 0" class="empty">
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>

View file

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps">
<div v-if="items.length === 0" class="empty">
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div>
<div class="_fullinfo">
<img :src="notFoundImageUrl" class="_ghost"/>
<img :src="notFoundImageUrl" draggable="false"/>
<div>{{ i18n.ts.notFoundDescription }}</div>
</div>
</div>

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header><MkPageHeader v-model:tab="tab" :tabs="headerTabs"/></template>
<MkSpacer v-if="error != null" :contentMax="1200">
<div :class="$style.root">
<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
<img :class="$style.img" :src="serverErrorImageUrl" draggable="false"/>
<p :class="$style.text">
<i class="ti ti-alert-triangle"></i>
{{ error }}
@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="role">{{ role.description }}</div>
<MkUserList v-if="visible" :pagination="users" :extractor="(item) => item.user"/>
<div v-else-if="!visible" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>
@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer v-else-if="tab === 'timeline'" :contentMax="700">
<MkTimeline v-if="visible" ref="timeline" src="role" :role="props.roleId"/>
<div v-else-if="!visible" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</MkSpacer>
@ -38,12 +38,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, watch, ref } from 'vue';
import * as Misskey from 'misskey-js';
import { instanceName } from '@@/js/config.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import MkUserList from '@/components/MkUserList.vue';
import { definePage } from '@/page.js';
import { i18n } from '@/i18n.js';
import MkTimeline from '@/components/MkTimeline.vue';
import { instanceName } from '@@/js/config.js';
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
const props = withDefaults(defineProps<{

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormPagination ref="list" :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</template>

View file

@ -72,7 +72,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="renoteMutingPagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noUsers }}</div>
</div>
</template>
@ -108,7 +108,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="mutingPagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noUsers }}</div>
</div>
</template>
@ -146,7 +146,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="blockingPagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.noUsers }}</div>
</div>
</template>

View file

@ -214,11 +214,6 @@ rt {
text-overflow: ellipsis;
}
._ghost {
@extend ._noSelect;
pointer-events: none;
}
._modalBg {
position: fixed;
top: 0;

View file

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="body">
<div class="left">
<button v-click-anime class="item _button instance" @click="openInstanceMenu">
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" draggable="false"/>
</button>
<MkA v-click-anime v-tooltip="i18n.ts.timeline" class="item index" activeClass="active" to="/" exact>
<i class="ti ti-home ti-fw"></i>

View file

@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="divider"></div>
<div class="about">
<button v-click-anime class="item _button" @click="openInstanceMenu">
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" draggable="false"/>
</button>
</div>
<!--<MisskeyLogo class="misskey"/>-->

View file

@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkAvatar v-for="user in users" :key="user.id" :user="user.followee" link preview></MkAvatar>
</div>
<div v-else :class="$style.bdayFFallback">
<img :src="infoImageUrl" class="_ghost" :class="$style.bdayFFallbackImage"/>
<img :src="infoImageUrl" draggable="false" :class="$style.bdayFFallbackImage"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>

View file

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="ekmkgxbj">
<MkLoading v-if="fetching"/>
<div v-else-if="(!items || items.length === 0) && widgetProps.showHeader" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img :src="infoImageUrl" draggable="false"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
<div v-else :class="$style.feed">
@ -25,13 +25,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref, watch, computed } from 'vue';
import * as Misskey from 'misskey-js';
import { url as base } from '@@/js/config.js';
import { useInterval } from '@@/js/use-interval.js';
import { useWidgetPropsManager } from './widget.js';
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
import type { GetFormResultType } from '@/utility/form.js';
import MkContainer from '@/components/MkContainer.vue';
import { url as base } from '@@/js/config.js';
import { i18n } from '@/i18n.js';
import { useInterval } from '@@/js/use-interval.js';
import { infoImageUrl } from '@/instance.js';
const name = 'rss';