feat: 振動機能をサポート
This commit is contained in:
parent
f2d44d5c8a
commit
9a55f9a0f8
|
@ -39,6 +39,7 @@
|
|||
- Feat: 어떤 이유로 클라이언트의 이모티콘 캐시가 삭제된 경우 즉시 다시 가져오도록 (MisskeyIO/misskey#163)
|
||||
- Feat: 노트 작성 폼에 MFM 도움말을 볼 수 있는 버튼 추가
|
||||
- Feat: 새 MFM 구문 추가 (페이드)
|
||||
- Feat: 햅틱 피드백 지원
|
||||
- Enhance: 노트의 리액션을 삭제하지 않고도 리액션 버튼을 눌러 리액션을 변경할 수 있도록 (misskey-dev/misskey#11157)
|
||||
- Enhance: 이용 약관을 서버 메뉴에서 볼 수 있도록
|
||||
- Enhance: 설정에서 변경 가능한 옵션은 다이얼로그에서 안내하도록 설명 추가
|
||||
|
|
|
@ -592,6 +592,10 @@ showFixedPostFormInChannel: "Display the posting form at the top of the timeline
|
|||
newNoteRecived: "There are new notes"
|
||||
sounds: "Sounds"
|
||||
sound: "Sounds"
|
||||
vibrations: "Vibrations"
|
||||
soundsAndVibrations: "Sounds and Vibrations"
|
||||
playVibrationsOnClick: "Play vibrations on click"
|
||||
playVibrationsOnClickDescription: "This feature is not supported on iOS/iPadOS."
|
||||
listen: "Listen"
|
||||
none: "None"
|
||||
showInPage: "Show in page"
|
||||
|
|
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
|
@ -595,6 +595,10 @@ export interface Locale {
|
|||
"newNoteRecived": string;
|
||||
"sounds": string;
|
||||
"sound": string;
|
||||
"vibrations": string;
|
||||
"soundsAndVibrations": string;
|
||||
"playVibrationsOnClick": string;
|
||||
"playVibrationsOnClickDescription": string;
|
||||
"listen": string;
|
||||
"none": string;
|
||||
"showInPage": string;
|
||||
|
|
|
@ -592,6 +592,10 @@ showFixedPostFormInChannel: "タイムライン上部に投稿フォームを表
|
|||
newNoteRecived: "新しいノートがあります"
|
||||
sounds: "サウンド"
|
||||
sound: "サウンド"
|
||||
vibrations: "振動"
|
||||
soundsAndVibrations: "サウンドと振動"
|
||||
playVibrationsOnClick: "クリック時の振動再生"
|
||||
playVibrationsOnClickDescription: "この機能はiOS/iPadOSではサポートされていません。"
|
||||
listen: "聴く"
|
||||
none: "なし"
|
||||
showInPage: "ページで表示"
|
||||
|
|
|
@ -590,6 +590,10 @@ newNoteRecived: "새 노트가 있어요!"
|
|||
newNoteRecivedCount: "{n}개의 새 노트가 있어요!"
|
||||
sounds: "소리"
|
||||
sound: "소리"
|
||||
vibrations: "진동"
|
||||
soundsAndVibrations: "소리 및 진동"
|
||||
playVibrationsOnClick: "클릭 시 진동 재생"
|
||||
playVibrationsOnClickDescription: "이 기능은 iOS/iPadOS에서는 지원되지 않아요."
|
||||
listen: "듣기"
|
||||
none: "없음"
|
||||
showInPage: "페이지로 보기"
|
||||
|
|
|
@ -34,6 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted } from 'vue';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
const props = defineProps<{
|
||||
type?: 'button' | 'submit' | 'reset';
|
||||
|
@ -99,6 +100,8 @@ function onMousedown(evt: MouseEvent): void {
|
|||
|
||||
const scale = calcCircleScale(target.clientWidth, target.clientHeight, circleCenterX, circleCenterY);
|
||||
|
||||
vibrate(10);
|
||||
|
||||
window.setTimeout(() => {
|
||||
ripple.style.transform = 'scale(' + (scale / 2) + ')';
|
||||
}, 1);
|
||||
|
|
|
@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
>
|
||||
<div v-show="showBody" ref="contentEl" :class="[$style.content, { [$style.omitted]: omitted }]">
|
||||
<slot></slot>
|
||||
<button v-if="omitted" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
|
||||
<button v-if="omitted" v-vibrate="5" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
|
||||
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<button
|
||||
v-for="emoji in searchResultCustom"
|
||||
:key="emoji.name"
|
||||
v-vibrate="50"
|
||||
class="_button item"
|
||||
:title="emoji.name"
|
||||
tabindex="0"
|
||||
|
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div ref="rootEl" :class="$style.root" role="group" :aria-expanded="opened">
|
||||
<MkStickyContainer>
|
||||
<template #header>
|
||||
<div :class="[$style.header, { [$style.opened]: opened, [$style.inactive]: inactive || isArchived }]" class="_button" role="button" data-cy-folder-header @click="toggle">
|
||||
<div v-vibrate="5" :class="[$style.header, { [$style.opened]: opened, [$style.inactive]: inactive || isArchived }]" class="_button" role="button" data-cy-folder-header @click="toggle">
|
||||
<div :class="$style.headerIcon"><slot name="icon"></slot></div>
|
||||
<div :class="$style.headerText">
|
||||
<div>
|
||||
|
|
|
@ -46,6 +46,7 @@ import { claimAchievement } from '@/scripts/achievements.js';
|
|||
import { $i } from '@/account.js';
|
||||
import { userName } from '@/filters/user.js';
|
||||
import { globalEvents } from '@/events.js';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
let showFollowButton = $ref(false);
|
||||
|
||||
|
@ -108,6 +109,7 @@ async function onClick() {
|
|||
await os.api('following/create', {
|
||||
userId: props.user.id,
|
||||
});
|
||||
vibrate([30, 40, 100]);
|
||||
hasPendingFollowRequestFromYou = true;
|
||||
|
||||
claimAchievement('following1');
|
||||
|
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<div role="menu">
|
||||
<div
|
||||
ref="itemsEl" v-hotkey="keymap"
|
||||
ref="itemsEl" v-hotkey="keymap" v-vibrate="5"
|
||||
class="_popup _shadow"
|
||||
:class="[$style.root, { [$style.center]: align === 'center', [$style.asDrawer]: asDrawer }]"
|
||||
:style="{ width: (width && !asDrawer) ? width + 'px' : '', maxHeight: maxHeight ? maxHeight + 'px' : '' }"
|
||||
|
|
|
@ -9,6 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
v-show="!isDeleted"
|
||||
ref="el"
|
||||
v-hotkey="keymap"
|
||||
v-vibrate="5"
|
||||
:class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover, [$style.radius]: defaultStore.state.showGapBetweenNotesInTimeline && mainRouter.currentRoute.value.name === 'my-notifications' }]"
|
||||
:tabindex="!isDeleted ? '-1' : undefined"
|
||||
>
|
||||
|
@ -98,10 +99,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
|
||||
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
|
||||
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" :class="$style.collapsed" class="_button" @click="collapsed = false">
|
||||
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" v-vibrate="5" :class="$style.collapsed" class="_button" @click="collapsed = false">
|
||||
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -115,13 +116,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
</MkReactionsViewer>
|
||||
<footer :class="$style.footer">
|
||||
<button v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
|
||||
<button v-vibrate="5" v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
|
||||
<i class="ti ti-arrow-back-up"></i>
|
||||
<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ appearNote.repliesCount }}</p>
|
||||
</button>
|
||||
<button
|
||||
v-if="canRenote"
|
||||
ref="renoteButton"
|
||||
v-vibrate="[30, 30, 60]"
|
||||
v-tooltip="i18n.ts.renote"
|
||||
:class="$style.footerButton"
|
||||
class="_button"
|
||||
|
@ -133,26 +135,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<button v-else :class="$style.footerButton" class="_button" disabled>
|
||||
<i class="ti ti-ban"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
|
||||
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
|
||||
<i class="ti ti-heart"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
|
||||
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
|
||||
<i v-if="appearNote.myReaction == null" class="ti ti-mood-plus"></i>
|
||||
<i v-else class="ti ti-mood-edit"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" :class="$style.footerButton" class="_button" @click="undoReact(appearNote)">
|
||||
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" :class="$style.footerButton" class="_button" @click="undoReact(appearNote)">
|
||||
<i class="ti ti-heart-minus"></i>
|
||||
</button>
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
|
||||
<i class="ti ti-quote"></i>
|
||||
</button>
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="5" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
|
||||
<i class="ti ti-paperclip"></i>
|
||||
</button>
|
||||
<MkA v-if="defaultStore.state.infoButtonForNoteActionsEnabled && defaultStore.state.showNoteActionsOnlyHover" v-tooltip="i18n.ts.details" :to="notePage(note)" :class="$style.footerButton" style="text-decoration: none;" class="_button">
|
||||
<i class="ti ti-info-circle"></i>
|
||||
</MkA>
|
||||
<button ref="menuButton" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
|
||||
<button ref="menuButton" v-vibrate="5" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
|
||||
<i class="ti ti-dots"></i>
|
||||
</button>
|
||||
</footer>
|
||||
|
|
|
@ -129,13 +129,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
</div>
|
||||
<MkReactionsViewer ref="reactionsViewer" :note="appearNote"/>
|
||||
<button v-tooltip="i18n.ts.reply" class="_button" :class="$style.noteFooterButton" @click="reply()">
|
||||
<button v-vibrate="5" v-tooltip="i18n.ts.reply" class="_button" :class="$style.noteFooterButton" @click="reply()">
|
||||
<i class="ti ti-arrow-back-up"></i>
|
||||
<p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.repliesCount }}</p>
|
||||
</button>
|
||||
<button
|
||||
v-if="canRenote"
|
||||
ref="renoteButton"
|
||||
v-vibrate="[30, 30, 60]"
|
||||
v-tooltip="i18n.ts.renote"
|
||||
class="_button"
|
||||
:class="$style.noteFooterButton"
|
||||
|
@ -147,23 +148,23 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<button v-else class="_button" :class="$style.noteFooterButton" disabled>
|
||||
<i class="ti ti-ban"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-tooltip="i18n.ts.like" :class="$style.noteFooterButton" class="_button" @mousedown="heartReact()">
|
||||
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.noteFooterButton" class="_button" @mousedown="heartReact()">
|
||||
<i class="ti ti-heart"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-tooltip="i18n.ts.reaction" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
|
||||
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
|
||||
<i v-if="appearNote.myReaction == null" class="ti ti-mood-plus"></i>
|
||||
<i v-else class="ti ti-mood-edit"></i>
|
||||
</button>
|
||||
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" :class="[$style.noteFooterButton, $style.reacted]" class="_button" @click="undoReact(appearNote)">
|
||||
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" :class="[$style.noteFooterButton, $style.reacted]" class="_button" @click="undoReact(appearNote)">
|
||||
<i class="ti ti-heart-minus"></i>
|
||||
</button>
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-tooltip="i18n.ts.quote" class="_button" :class="$style.noteFooterButton" @mousedown="quote()">
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.noteFooterButton" @mousedown="quote()">
|
||||
<i class="ti ti-quote"></i>
|
||||
</button>
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-tooltip="i18n.ts.clip" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="5" v-tooltip="i18n.ts.clip" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
|
||||
<i class="ti ti-paperclip"></i>
|
||||
</button>
|
||||
<button ref="menuButton" v-tooltip="i18n.ts.more" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
||||
<button ref="menuButton" v-vibrate="5" v-tooltip="i18n.ts.more" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
||||
<i class="ti ti-dots"></i>
|
||||
</button>
|
||||
</footer>
|
||||
|
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<div ref="content" :class="[$style.content, { [$style.omitted]: omitted }]">
|
||||
<slot></slot>
|
||||
<button v-if="omitted" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
|
||||
<button v-if="omitted" v-vibrate="5" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
|
||||
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -129,6 +129,7 @@ import { deepClone } from '@/scripts/clone.js';
|
|||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
const modal = inject('modal');
|
||||
|
||||
|
@ -848,6 +849,7 @@ async function post(ev?: MouseEvent) {
|
|||
text: err.message + '\n' + (err as any).id,
|
||||
});
|
||||
});
|
||||
vibrate([10, 20, 10, 20, 10, 20, 60]);
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
|
|
|
@ -149,6 +149,7 @@ import { deepClone } from '@/scripts/clone.js';
|
|||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { claimAchievement } from '@/scripts/achievements.js';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
const modal = inject('modal');
|
||||
|
||||
|
@ -866,6 +867,7 @@ async function post(ev?: MouseEvent) {
|
|||
text: err.message + '\n' + (err as any).id,
|
||||
});
|
||||
});
|
||||
vibrate([10, 20, 10, 20, 10, 20, 60]);
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
|
|
|
@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<div
|
||||
v-adaptive-border
|
||||
v-vibrate="5"
|
||||
:class="[$style.root, { [$style.disabled]: disabled, [$style.checked]: checked }]"
|
||||
:aria-checked="checked"
|
||||
:aria-disabled="disabled"
|
||||
|
|
|
@ -24,6 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<script lang="ts" setup>
|
||||
import { computed, defineAsyncComponent, onMounted, onUnmounted, ref, watch, shallowRef } from 'vue';
|
||||
import * as os from '@/os.js';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue: number;
|
||||
|
@ -100,6 +101,8 @@ const steps = computed(() => {
|
|||
});
|
||||
|
||||
const onMousedown = (ev: MouseEvent | TouchEvent) => {
|
||||
vibrate(10);
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
const tooltipShowing = ref(true);
|
||||
|
|
|
@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<button
|
||||
ref="buttonEl"
|
||||
v-ripple="canToggle"
|
||||
v-vibrate="[10, 30, 40]"
|
||||
class="_button"
|
||||
:class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: (canToggle || alternative), [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]"
|
||||
@click="toggleReaction()"
|
||||
|
|
|
@ -37,10 +37,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" :class="$style.fade" class="_button" @click="collapsed = false">
|
||||
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" v-vibrate="5" :class="$style.fade" class="_button" @click="collapsed = false">
|
||||
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
|
||||
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
||||
</button>
|
||||
<div v-if="showSubNoteFooterButton">
|
||||
|
@ -52,13 +52,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
</MkReactionsViewer>
|
||||
<footer :class="$style.footer">
|
||||
<button v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
|
||||
<button v-vibrate="5" v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
|
||||
<i class="ti ti-arrow-back-up"></i>
|
||||
<p v-if="note.repliesCount > 0" :class="$style.footerButtonCount">{{ note.repliesCount }}</p>
|
||||
</button>
|
||||
<button
|
||||
v-if="canRenote"
|
||||
ref="renoteButton"
|
||||
v-vibrate="[30, 30, 60]"
|
||||
v-tooltip="i18n.ts.renote"
|
||||
:class="$style.footerButton"
|
||||
class="_button"
|
||||
|
@ -70,26 +71,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<button v-else :class="$style.footerButton" class="_button" disabled>
|
||||
<i class="ti ti-ban"></i>
|
||||
</button>
|
||||
<button v-if="note.myReaction == null" ref="heartReactButton" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
|
||||
<button v-if="note.myReaction == null" ref="heartReactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
|
||||
<i class="ti ti-heart"></i>
|
||||
</button>
|
||||
<button v-if="note.myReaction == null && note.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
|
||||
<button v-if="note.myReaction == null && note.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
|
||||
<i class="ti ti-mood-plus"></i>
|
||||
</button>
|
||||
<button v-if="note.myReaction != null" ref="reactButton" :class="$style.footerButton" class="_button" @click="undoReact(note)">
|
||||
<button v-if="note.myReaction != null" ref="reactButton" v-vibrate="[30, 50, 50]" :class="$style.footerButton" class="_button" @click="undoReact(note)">
|
||||
<i v-if="note.reactionAcceptance !== 'likeOnly'" class="ti ti-mood-minus"></i>
|
||||
<i v-else class="ti ti-heart-minus"></i>
|
||||
</button>
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
|
||||
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
|
||||
<i class="ti ti-quote"></i>
|
||||
</button>
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
|
||||
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="5" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
|
||||
<i class="ti ti-paperclip"></i>
|
||||
</button>
|
||||
<MkA v-if="defaultStore.state.infoButtonForNoteActionsEnabled && defaultStore.state.showNoteActionsOnlyHover" v-tooltip="i18n.ts.details" :to="notePage(note)" :class="$style.footerButton" style="text-decoration: none;" class="_button">
|
||||
<i class="ti ti-info-circle"></i>
|
||||
</MkA>
|
||||
<button ref="menuButton" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
|
||||
<button ref="menuButton" v-vibrate="5" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
|
||||
<i class="ti ti-dots"></i>
|
||||
</button>
|
||||
</footer>
|
||||
|
|
|
@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<span
|
||||
v-vibrate="5"
|
||||
v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff"
|
||||
:class="{
|
||||
[$style.button]: true,
|
||||
|
|
|
@ -6,10 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<div v-if="show" ref="el" :class="[$style.root, {[$style.slim]: narrow, [$style.thin]: thin_, [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect }]" :style="{ background: bg }">
|
||||
<div v-if="!thin_ && !canBack" :class="$style.buttonsLeft">
|
||||
<button class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
<button v-vibrate="5" class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
</div>
|
||||
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i && !isFriendly" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
||||
<MkAvatar :class="$style.avatar" :user="$i"/>
|
||||
<MkAvatar v-vibrate="5" :class="$style.avatar" :user="$i"/>
|
||||
</div>
|
||||
<div v-else-if="!thin_ && narrow && !hideTitle && canBack" :class="$style.buttonsLeft"/>
|
||||
<div v-else-if="!thin_ && canBack && (actions && actions.length > 0)" :class="$style.buttonsLeft"/>
|
||||
|
@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="!thin_ && !narrow && (actions && actions.length > 0) && hideTitle && ['index'].includes(<string>mainRouter.currentRoute.value.name)" :class="$style.buttonsRight"/>
|
||||
<div v-else-if="(!thin_ && narrow && !hideTitle) || (actions && actions.length > 0)" :class="$style.buttonsRight">
|
||||
<template v-for="action in actions">
|
||||
<button v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else-if="!thin_ && !canBack && !(actions && actions.length > 0)" :class="$style.buttonsRight"/>
|
||||
|
|
|
@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
-->
|
||||
|
||||
<template>
|
||||
<a :href="to" :class="active ? activeClass : null" @click.prevent="nav" @contextmenu.prevent.stop="onContextmenu">
|
||||
<a v-vibrate="5" :href="to" :class="active ? activeClass : null" @click.prevent="nav" @contextmenu.prevent.stop="onContextmenu">
|
||||
<slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div ref="el" :class="$style.tabs" @wheel="onTabWheel">
|
||||
<div :class="$style.tabsInner">
|
||||
<button
|
||||
v-for="t in tabs" :ref="(el) => tabRefs[t.key] = (el as HTMLElement)" v-tooltip.noDelay="t.title"
|
||||
v-for="t in tabs" :ref="(el) => tabRefs[t.key] = (el as HTMLElement)" v-vibrate="5" v-tooltip.noDelay="t.title"
|
||||
class="_button" :class="[$style.tab, { [$style.active]: t.key != null && t.key === props.tab, [$style.animate]: defaultStore.reactiveState.animation.value }]"
|
||||
@mousedown="(ev) => onTabMousedown(t, ev)" @click="(ev) => onTabClick(t, ev)"
|
||||
>
|
||||
|
|
|
@ -7,10 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="show" ref="el" :class="[$style.root, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect }]" :style="{ background: bg }">
|
||||
<div :class="[$style.upper, { [$style.slim]: narrow || isFriendly, [$style.thin]: thin_, [$style.hideTitle]: hideTitle && isFriendly }]">
|
||||
<div v-if="!thin_ && !canBack" :class="$style.buttonsLeft">
|
||||
<button class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
<button v-vibrate="5" class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
</div>
|
||||
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i && !isFriendly" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
||||
<MkAvatar :class="$style.avatar" :user="$i"/>
|
||||
<MkAvatar v-vibrate="5" :class="$style.avatar" :user="$i"/>
|
||||
</div>
|
||||
<div v-else-if="!thin_ && narrow && !hideTitle && canBack" :class="$style.buttonsLeft"/>
|
||||
<div v-else-if="!thin_ && canBack && (actions && actions.length > 0)" :class="$style.buttonsLeft"/>
|
||||
|
@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="!thin_ && !narrow && (actions && actions.length > 0) && hideTitle && ['index'].includes(<string>mainRouter.currentRoute.value.name)" :class="$style.buttonsRight"/>
|
||||
<div v-else-if="(!thin_ && narrow && !hideTitle) || (actions && actions.length > 0)" :class="$style.buttonsRight">
|
||||
<template v-for="action in actions">
|
||||
<button v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else-if="!thin_ && !canBack && !(actions && actions.length > 0)" :class="$style.buttonsRight"/>
|
||||
|
|
|
@ -16,6 +16,7 @@ import clickAnime from './click-anime';
|
|||
import panel from './panel';
|
||||
import adaptiveBorder from './adaptive-border';
|
||||
import adaptiveBg from './adaptive-bg';
|
||||
import vibrate from './vibrate';
|
||||
|
||||
export default function(app: App) {
|
||||
for (const [key, value] of Object.entries(directives)) {
|
||||
|
@ -36,4 +37,5 @@ export const directives = {
|
|||
'panel': panel,
|
||||
'adaptive-border': adaptiveBorder,
|
||||
'adaptive-bg': adaptiveBg,
|
||||
'vibrate': vibrate,
|
||||
};
|
||||
|
|
16
packages/frontend/src/directives/vibrate.ts
Normal file
16
packages/frontend/src/directives/vibrate.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: noridev and other cherrypick contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { Directive } from 'vue';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const pattern = (binding.value as VibratePattern) ?? 20;
|
||||
el.addEventListener('mousedown', () => {
|
||||
vibrate(pattern);
|
||||
});
|
||||
},
|
||||
} as Directive;
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<div ref="el" class="fdidabkc" :style="{ background: bg }" @click="onClick">
|
||||
<div class="buttons left">
|
||||
<button class="_button button goBack" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
<button v-vibrate="5" class="_button button goBack" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
|
||||
</div>
|
||||
<template v-if="metadata">
|
||||
<div class="titleContainer" @click="showTabsPopup">
|
||||
|
@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template v-if="actions">
|
||||
<template v-for="action in actions">
|
||||
<MkButton v-if="action.asFullButton" class="fullButton" primary @click.stop="action.handler"><i :class="action.icon" style="margin-right: 6px;"></i>{{ action.text }}</MkButton>
|
||||
<button v-else v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
<button v-else v-vibrate="5" v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -77,6 +77,7 @@ import { i18n } from '@/i18n.js';
|
|||
import { $i } from '@/account.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||
import { vibrate } from '@/scripts/vibrate.js';
|
||||
|
||||
const props = defineProps<{
|
||||
userAcct?: string;
|
||||
|
@ -214,6 +215,7 @@ function onDrop(ev: DragEvent): void {
|
|||
|
||||
function onMessage(message) {
|
||||
sound.play('chat');
|
||||
vibrate([30, 30, 30]);
|
||||
|
||||
const _isBottom = isBottomVisible(rootEl, 64);
|
||||
|
||||
|
|
|
@ -128,9 +128,9 @@ const menuDef = computed(() => [{
|
|||
active: currentPage?.route.name === 'statusbar',
|
||||
}, {
|
||||
icon: 'ti ti-music',
|
||||
text: i18n.ts.sounds,
|
||||
to: '/settings/sounds',
|
||||
active: currentPage?.route.name === 'sounds',
|
||||
text: i18n.ts.soundsAndVibrations,
|
||||
to: '/settings/sounds-and-vibrations',
|
||||
active: currentPage?.route.name === 'sounds-and-vibrations',
|
||||
}, {
|
||||
icon: 'ti ti-plug',
|
||||
text: i18n.ts.plugins,
|
||||
|
|
|
@ -128,6 +128,15 @@ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
|
|||
'darkTheme',
|
||||
'syncDeviceDarkMode',
|
||||
'plugins',
|
||||
'vibrate',
|
||||
'sound_masterVolume',
|
||||
'sound_note',
|
||||
'sound_noteMy',
|
||||
'sound_notification',
|
||||
'sound_chat',
|
||||
'sound_chatBg',
|
||||
'sound_antenna',
|
||||
'sound_channel',
|
||||
];
|
||||
|
||||
const scope = ['clientPreferencesProfiles'];
|
||||
|
|
|
@ -22,6 +22,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</FormSection>
|
||||
|
||||
<MkButton danger @click="reset()"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</MkButton>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ i18n.ts.vibration }}</template>
|
||||
<div class="_gaps_s">
|
||||
<MkSwitch v-model="vibrate" @click="demoVibrate()">{{ i18n.ts.playVibrationsOnClick }}<template #caption>{{ i18n.ts.playVibrationsOnClickDescription }}</template> <span class="_beta">CherryPick</span></MkSwitch>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -32,9 +39,11 @@ import MkRange from '@/components/MkRange.vue';
|
|||
import MkButton from '@/components/MkButton.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import { soundConfigStore } from '@/scripts/sound.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||
import { ColdDeviceStorage } from '@/store.js';
|
||||
|
||||
const masterVolume = computed(soundConfigStore.makeGetterSetter('sound_masterVolume'));
|
||||
|
||||
|
@ -50,6 +59,8 @@ const sounds = ref<Record<typeof soundsKeys[number], Ref<any>>>({
|
|||
channel: soundConfigStore.reactiveState.sound_channel,
|
||||
});
|
||||
|
||||
const vibrate = computed(ColdDeviceStorage.makeGetterSetter('vibrate'));
|
||||
|
||||
async function updated(type: keyof typeof sounds.value, sound) {
|
||||
const v = {
|
||||
type: sound.type,
|
||||
|
@ -68,12 +79,16 @@ function reset() {
|
|||
}
|
||||
}
|
||||
|
||||
function demoVibrate() {
|
||||
window.navigator.vibrate(100);
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
|
||||
definePageMetadata({
|
||||
title: i18n.ts.sounds,
|
||||
title: i18n.ts.soundsAndVibrations,
|
||||
icon: 'ti ti-music',
|
||||
});
|
||||
</script>
|
|
@ -115,9 +115,9 @@ export const routes = [{
|
|||
name: 'statusbar',
|
||||
component: page(() => import('./pages/settings/statusbar.vue')),
|
||||
}, {
|
||||
path: '/sounds',
|
||||
name: 'sounds',
|
||||
component: page(() => import('./pages/settings/sounds.vue')),
|
||||
path: '/sounds-and-vibrations',
|
||||
name: 'sounds-and-vibrations',
|
||||
component: page(() => import('./pages/settings/sounds-and-vibrations.vue')),
|
||||
}, {
|
||||
path: '/plugin/install',
|
||||
name: 'plugin',
|
||||
|
|
12
packages/frontend/src/scripts/vibrate.ts
Normal file
12
packages/frontend/src/scripts/vibrate.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: noridev and other cherrypick contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { ColdDeviceStorage } from '@/store.js';
|
||||
|
||||
export function vibrate(pattern: VibratePattern) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (!ColdDeviceStorage.get('vibrate') || !window.navigator.vibrate) return;
|
||||
window.navigator.vibrate(pattern);
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { markRaw, ref } from 'vue';
|
||||
import * as Misskey from 'cherrypick-js';
|
||||
import { miLocalStorage } from './local-storage';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { Storage } from '@/pizzax.js';
|
||||
|
||||
interface PostFormAction {
|
||||
|
@ -583,6 +583,7 @@ export class ColdDeviceStorage {
|
|||
syncDeviceDarkMode: true,
|
||||
plugins: [] as Plugin[],
|
||||
mediaVolume: 0.5,
|
||||
vibrate: true,
|
||||
sound_masterVolume: 0.5,
|
||||
sound_note: { type: 'syuilo/down', volume: 0.5 },
|
||||
sound_noteMy: { type: 'syuilo/up', volume: 0.5 },
|
||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="['all', 'bg'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<div :class="$style.top">
|
||||
<div v-if="['all', 'topBottom', 'top'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<button v-vibrate="5" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<div v-if="item === '-'" :class="$style.divider"></div>
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" class="_button" :class="[$style.item, { [$style.active]: navbarItemDef[item].active }]" :activeClass="$style.active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-vibrate="5" class="_button" :class="[$style.item, { [$style.active]: navbarItemDef[item].active }]" :activeClass="$style.active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<i class="ti-fw" :class="[$style.itemIcon, navbarItemDef[item].icon]"></i><span :class="$style.itemText">{{ navbarItemDef[item].title }}</span>
|
||||
<span v-if="navbarItemDef[item].indicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</component>
|
||||
|
@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="controlPanelIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</MkA>
|
||||
<button :class="$style.item" class="_button" @click="more">
|
||||
<button v-vibrate="5" :class="$style.item" class="_button" @click="more">
|
||||
<i :class="$style.itemIcon" class="ti ti-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
|
||||
<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -38,10 +38,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<div :class="$style.bottom">
|
||||
<div v-if="['all', 'topBottom', 'bottom'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.bottomBanner]" :style="{ backgroundImage: `url(${ $i.bannerUrl })` }"></div>
|
||||
<button class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
|
||||
<button v-vibrate="5" class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
|
||||
<i :class="[$style.postIcon, defaultStore.state.renameTheButtonInPostFormToNya ? 'ti-paw-filled' : 'ti-pencil']" class="ti ti-fw"></i><span style="position: relative;">{{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}</span>
|
||||
</button>
|
||||
<button class="_button" :class="$style.account" @click="openAccountMenu">
|
||||
<button v-vibrate="5" class="_button" :class="$style.account" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" :class="$style.avatar"/><MkAcct :class="$style.acct" class="_nowrap" :user="$i"/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="['all', 'bg'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<div :class="$style.top">
|
||||
<div v-if="['all', 'topBottom', 'top'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<button v-vibrate="5" v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<component
|
||||
:is="navbarItemDef[item].to ? 'MkA' : 'button'"
|
||||
v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)"
|
||||
v-vibrate="5"
|
||||
v-tooltip.noDelay.right="navbarItemDef[item].title"
|
||||
class="_button"
|
||||
:class="[$style.item, { [$style.active]: navbarItemDef[item].active }]"
|
||||
|
@ -38,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="controlPanelIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</MkA>
|
||||
<button class="_button" :class="$style.item" @click="more">
|
||||
<button v-vibrate="5" class="_button" :class="$style.item" @click="more">
|
||||
<i :class="$style.itemIcon" class="ti ti-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
|
||||
<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -48,10 +49,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<div :class="$style.bottom">
|
||||
<div v-if="['all', 'topBottom', 'bottom'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.bottomBanner]" :style="{ backgroundImage: `url(${ $i.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note" class="_button" :class="[$style.post]" data-cy-open-post-form @click="os.post">
|
||||
<button v-vibrate="5" v-tooltip.noDelay.right="defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note" class="_button" :class="[$style.post]" data-cy-open-post-form @click="os.post">
|
||||
<i class="ti ti-fw" :class="[$style.postIcon, defaultStore.state.renameTheButtonInPostFormToNya ? 'ti-paw-filled' : 'ti-pencil']"></i><span :class="$style.postText">{{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}</span>
|
||||
</button>
|
||||
<button v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
|
||||
<button v-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" :class="$style.avatar"/><MkAcct class="_nowrap" :class="$style.acct" :user="$i"/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div class="azykntjl">
|
||||
<div class="body">
|
||||
<div class="left">
|
||||
<button v-click-anime class="item _button instance" @click="openInstanceMenu">
|
||||
<button v-click-anime v-vibrate="5" class="item _button instance" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
|
||||
</button>
|
||||
<MkA v-click-anime v-tooltip="i18n.ts.timeline" class="item index" activeClass="active" to="/" exact>
|
||||
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<div v-if="item === '-'" class="divider"></div>
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-tooltip="navbarItemDef[item].title" class="item _button" :class="item" activeClass="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-vibrate="5" v-tooltip="navbarItemDef[item].title" class="item _button" :class="item" activeClass="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<i class="ti-fw" :class="navbarItemDef[item].icon"></i>
|
||||
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="_indicatorCircle"></i></span>
|
||||
</component>
|
||||
|
@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="i18n.ts.controlPanel" class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'window' : null">
|
||||
<i class="ti ti-dashboard ti-fw"></i>
|
||||
</MkA>
|
||||
<button v-click-anime class="item _button" @click="more">
|
||||
<button v-click-anime v-vibrate="5" class="item _button" @click="more">
|
||||
<i class="ti ti-dots ti-fw"></i>
|
||||
<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA v-click-anime v-tooltip="i18n.ts.settings" class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'window' : null">
|
||||
<i class="ti ti-settings ti-fw"></i>
|
||||
</MkA>
|
||||
<button v-click-anime class="item _button account" @click="openAccountMenu">
|
||||
<button v-click-anime v-vibrate="5" class="item _button account" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/>
|
||||
</button>
|
||||
<div class="post" @click="os.post()">
|
||||
|
|
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<div class="npcljfve" :class="{ iconOnly }">
|
||||
<button v-click-anime class="item _button account" @click="openAccountMenu">
|
||||
<button v-click-anime v-vibrate="5" class="item _button account" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
|
||||
</button>
|
||||
<div class="post" data-cy-open-post-form @click="os.post">
|
||||
|
@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<div v-if="item === '-'" class="divider"></div>
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime class="item _button" :class="item" activeClass="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-vibrate="5" class="item _button" :class="item" activeClass="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<i class="ti-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ navbarItemDef[item].title }}</span>
|
||||
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="_indicatorCircle"></i></span>
|
||||
</component>
|
||||
|
@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<i class="ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="controlPanelIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
|
||||
</MkA>
|
||||
<button v-click-anime class="item _button" @click="more">
|
||||
<button v-click-anime v-vibrate="5" class="item _button" @click="more">
|
||||
<i class="ti ti-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
|
||||
<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
<div class="divider"></div>
|
||||
<div class="about">
|
||||
<button v-click-anime class="item _button" @click="openInstanceMenu">
|
||||
<button v-click-anime v-vibrate="5" class="item _button" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -36,24 +36,24 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<div :class="$style.sideMenu">
|
||||
<div :class="$style.sideMenuTop">
|
||||
<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" :class="$style.sideMenuButton" class="_button" @click="changeProfile"><i class="ti ti-caret-down"></i></button>
|
||||
<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" :class="$style.sideMenuButton" class="_button" @click="changeProfile"><i class="ti ti-caret-down"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
|
||||
</div>
|
||||
<div :class="$style.sideMenuMiddle">
|
||||
<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
|
||||
</div>
|
||||
<div :class="$style.sideMenuBottom">
|
||||
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
|
||||
<button v-vibrate="5" v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isMobile" :class="$style.nav">
|
||||
<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="$style.navButton" class="_button" @click="mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
|
||||
<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
|
|
|
@ -26,20 +26,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<XWidgets/>
|
||||
</div>
|
||||
|
||||
<button v-if="isMobile && enableNavButton.includes(<string>mainRouter.currentRoute.value.name)" :class="[$style.floatNavButton, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect, [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="drawerMenuShowing = true"><CPAvatar :class="$style.floatNavButtonAvatar" :user="$i"/></button>
|
||||
<button v-if="isMobile && enableNavButton.includes(<string>mainRouter.currentRoute.value.name)" v-vibrate="5" :class="[$style.floatNavButton, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect, [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="drawerMenuShowing = true"><CPAvatar :class="$style.floatNavButtonAvatar" :user="$i"/></button>
|
||||
|
||||
<button v-if="isMobile && enablePostButton.includes(<string>mainRouter.currentRoute.value.name)" :class="[$style.floatPostButton, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect, [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" :style="{ background: PostBg }" class="_button" @click="openMessage"><span :class="[$style.floatPostButtonBg, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect }]"></span><i v-if="mainRouter.currentRoute.value.name === 'messaging' && !(['messaging-room', 'messaging-room-group'].includes(<string>mainRouter.currentRoute.value.name))" class="ti ti-plus"></i><i v-else-if="enablePostButton.includes(<string>mainRouter.currentRoute.value.name)" class="ti ti-pencil"></i></button>
|
||||
<button v-if="isMobile && enablePostButton.includes(<string>mainRouter.currentRoute.value.name)" v-vibrate="5" :class="[$style.floatPostButton, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect, [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" :style="{ background: PostBg }" class="_button" @click="openMessage"><span :class="[$style.floatPostButtonBg, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect }]"></span><i v-if="mainRouter.currentRoute.value.name === 'messaging' && !(['messaging-room', 'messaging-room-group'].includes(<string>mainRouter.currentRoute.value.name))" class="ti ti-plus"></i><i v-else-if="enablePostButton.includes(<string>mainRouter.currentRoute.value.name)" class="ti ti-pencil"></i></button>
|
||||
|
||||
<button v-if="!isDesktop && !isMobile" :class="[$style.widgetButton, { [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="widgetsShowing = true"><i class="ti ti-apps"></i></button>
|
||||
<button v-if="!isDesktop && !isMobile" v-vibrate="5" :class="[$style.widgetButton, { [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="widgetsShowing = true"><i class="ti ti-apps"></i></button>
|
||||
|
||||
<div v-if="isMobile" ref="navFooter" :class="[$style.nav, { [$style.reduceBlurEffect]: !defaultStore.state.useBlurEffect, [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" :style="{ background: bg }">
|
||||
<!-- <button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button> -->
|
||||
<button :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'index' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')" @touchstart="openAccountMenu" @touchend="closeAccountMenu"><i :class="$style.navButtonIcon" class="ti ti-home"></i><span v-if="queue > 0" :class="$style.navButtonIndicatorHome"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'explore' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'explore' ? top() : mainRouter.push('/explore')"><i :class="$style.navButtonIcon" class="ti ti-hash"></i></button>
|
||||
<button :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'my-notifications' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'my-notifications' ? top() : mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="[$style.navButton, { [$style.active]: ['messaging', 'messaging-room', 'messaging-room-group'].includes(<string>mainRouter.currentRoute.value.name) }]" class="_button" @click="mainRouter.currentRoute.value.name === 'messaging' ? top() : mainRouter.push('/my/messaging')"><i :class="$style.navButtonIcon" class="ti ti-messages"></i><span v-if="$i?.hasUnreadMessagingMessage" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
|
||||
<!-- <button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button> -->
|
||||
<!-- v-vibrate="5" <button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button> -->
|
||||
<button v-vibrate="5" :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'index' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')" @touchstart="openAccountMenu" @touchend="closeAccountMenu"><i :class="$style.navButtonIcon" class="ti ti-home"></i><span v-if="queue > 0" :class="$style.navButtonIndicatorHome"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'explore' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'explore' ? top() : mainRouter.push('/explore')"><i :class="$style.navButtonIcon" class="ti ti-hash"></i></button>
|
||||
<button v-vibrate="5" :class="[$style.navButton, { [$style.active]: mainRouter.currentRoute.value.name === 'my-notifications' }]" class="_button" @click="mainRouter.currentRoute.value.name === 'my-notifications' ? top() : mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="[$style.navButton, { [$style.active]: ['messaging', 'messaging-room', 'messaging-room-group'].includes(<string>mainRouter.currentRoute.value.name) }]" class="_button" @click="mainRouter.currentRoute.value.name === 'messaging' ? top() : mainRouter.push('/my/messaging')"><i :class="$style.navButtonIcon" class="ti ti-messages"></i><span v-if="$i?.hasUnreadMessagingMessage" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
|
||||
<!-- <button v-vibrate="5" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button> -->
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="['all', 'bg'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<div :class="$style.top">
|
||||
<div v-if="['all', 'topBottom', 'top'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<button v-vibrate="5" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkA>
|
||||
<template v-for="item in menu">
|
||||
<div v-if="item === '-'" :class="$style.divider"></div>
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" class="_button" :class="[$style.item, { [$style.active]: navbarItemDef[item].active }]" :activeClass="$style.active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-vibrate="5" class="_button" :class="[$style.item, { [$style.active]: navbarItemDef[item].active }]" :activeClass="$style.active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
|
||||
<i class="ti-fw" :class="[$style.itemIcon, navbarItemDef[item].icon]"></i><span :class="$style.itemText">{{ navbarItemDef[item].title }}</span>
|
||||
<span v-if="navbarItemDef[item].indicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</component>
|
||||
|
@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="controlPanelIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</MkA>
|
||||
<button :class="$style.item" class="_button" @click="more">
|
||||
<button v-vibrate="5" :class="$style.item" class="_button" @click="more">
|
||||
<i :class="$style.itemIcon" class="ti ti-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
|
||||
<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -38,14 +38,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<div :class="$style.bottom">
|
||||
<div v-if="['all', 'topBottom', 'bottom'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.bottomBanner]" :style="{ backgroundImage: `url(${ $i.bannerUrl })` }"></div>
|
||||
<button class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
|
||||
<button v-vibrate="5" class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
|
||||
<i :class="[$style.postIcon, defaultStore.state.renameTheButtonInPostFormToNya ? 'ti-paw-filled' : 'ti-pencil']" class="ti ti-fw"></i><span style="position: relative;">{{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}</span>
|
||||
</button>
|
||||
<div :class="$style.profile">
|
||||
<button class="_button" :class="$style.account" @click="openProfile">
|
||||
<button v-vibrate="5" class="_button" :class="$style.account" @click="openProfile">
|
||||
<MkAvatar :user="$i" :class="$style.avatar"/><MkUserName :class="$style.acct" class="_nowrap" :user="$i"/>
|
||||
</button>
|
||||
<button class="_button" :class="$style.drawer" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
|
||||
<button v-vibrate="5" class="_button" :class="$style.drawer" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div v-if="['all', 'bg'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<div :class="$style.top">
|
||||
<div v-if="['all', 'topBottom', 'top'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.topBanner]" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<button v-vibrate="5" v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.instanceIcon"/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<component
|
||||
:is="navbarItemDef[item].to ? 'MkA' : 'button'"
|
||||
v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)"
|
||||
v-vibrate="5"
|
||||
v-tooltip.noDelay.right="navbarItemDef[item].title"
|
||||
class="_button"
|
||||
:class="[$style.item, { [$style.active]: navbarItemDef[item].active }]"
|
||||
|
@ -38,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="controlPanelIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</MkA>
|
||||
<button class="_button" :class="$style.item" @click="more">
|
||||
<button v-vibrate="5" class="_button" :class="$style.item" @click="more">
|
||||
<i :class="$style.itemIcon" class="ti ti-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
|
||||
<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
|
||||
</button>
|
||||
|
@ -48,17 +49,17 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
<div :class="$style.bottom">
|
||||
<div v-if="['all', 'topBottom', 'bottom'].includes(<string>defaultStore.state.bannerDisplay)" :class="[$style.banner, $style.bottomBanner]" :style="{ backgroundImage: `url(${ $i.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note" class="_button" :class="[$style.post]" data-cy-open-post-form @click="os.post">
|
||||
<button v-vibrate="5" v-tooltip.noDelay.right="defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note" class="_button" :class="[$style.post]" data-cy-open-post-form @click="os.post">
|
||||
<i class="ti ti-fw" :class="[$style.postIcon, defaultStore.state.renameTheButtonInPostFormToNya ? 'ti-paw-filled' : 'ti-pencil']"></i><span :class="$style.postText">{{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}</span>
|
||||
</button>
|
||||
<div :class="$style.profile">
|
||||
<button v-if="iconOnly" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
|
||||
<button v-if="iconOnly" v-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" :class="$style.avatar"/>
|
||||
</button>
|
||||
<button v-else v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openProfile">
|
||||
<button v-else v-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openProfile">
|
||||
<MkAvatar :user="$i" :class="$style.avatar"/><MkUserName class="_nowrap" :class="$style.acct" :user="$i"/>
|
||||
</button>
|
||||
<button v-if="!iconOnly" class="_button" :class="[$style.drawer]" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
|
||||
<button v-if="!iconOnly" v-vibrate="5" class="_button" :class="[$style.drawer]" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,14 +22,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<XWidgets/>
|
||||
</div>
|
||||
|
||||
<button v-if="!isDesktop && !isMobile" :class="[$style.widgetButton, { [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="widgetsShowing = true"><i class="ti ti-apps"></i></button>
|
||||
<button v-if="!isDesktop && !isMobile" v-vibrate="5" :class="[$style.widgetButton, { [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideHeaderFloatBtn', 'hideFloatBtnOnly', 'hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]" class="_button" @click="widgetsShowing = true"><i class="ti ti-apps"></i></button>
|
||||
|
||||
<div v-if="isMobile" ref="navFooter" :class="[$style.nav, { [$style.reduceAnimation]: !defaultStore.state.animation, [$style.showEl]: (showEl && ['hideFloatBtnNavBar', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) }]">
|
||||
<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="$style.navButton" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
|
||||
<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
|
||||
<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
|
||||
<button v-vibrate="5" :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
|
||||
<button v-vibrate="5" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
|
|
|
@ -7,8 +7,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div>
|
||||
<XWidgets :edit="editMode" :widgets="widgets" @addWidget="addWidget" @removeWidget="removeWidget" @updateWidget="updateWidget" @updateWidgets="updateWidgets" @exit="editMode = false"/>
|
||||
|
||||
<button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ i18n.ts.editWidgetsExit }}</button>
|
||||
<button v-else class="_textButton" data-cy-widget-edit :class="$style.edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ i18n.ts.editWidgets }}</button>
|
||||
<button v-if="editMode" v-vibrate="5" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ i18n.ts.editWidgetsExit }}</button>
|
||||
<button v-else v-vibrate="5" class="_textButton" data-cy-widget-edit :class="$style.edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ i18n.ts.editWidgets }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA to="/channels" class="link" activeClass="active"><i class="ti ti-device-tv icon"></i> {{ i18n.ts.channel }}</MkA>
|
||||
</div>
|
||||
<div v-else-if="narrow === true" class="narrow">
|
||||
<button class="menu _button" @click="showMenu = true">
|
||||
<button v-vibrate="5" class="menu _button" @click="showMenu = true">
|
||||
<i class="ti ti-menu-2 icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -59,8 +59,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkA to="/play" class="link" activeClass="active"><i class="ti ti-player-play icon"></i>Play</MkA>
|
||||
<MkA to="/gallery" class="link" activeClass="active"><i class="ti ti-icons icon"></i>{{ i18n.ts.gallery }}</MkA>
|
||||
<div class="action">
|
||||
<button class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
|
||||
<button class="_button" @click="signin()">{{ i18n.ts.login }}</button>
|
||||
<button v-vibrate="5" class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
|
||||
<button v-vibrate="5" class="_button" @click="signin()">{{ i18n.ts.login }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
|
|
@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
See https://github.com/misskey-dev/misskey/issues/10905
|
||||
-->
|
||||
<div v-if="showBottom" :class="$style.bottom">
|
||||
<button v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ti ti-home"></i></button>
|
||||
<button v-vibrate="5" v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ti ti-home"></i></button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
Loading…
Reference in a new issue