enhance(frontend): 振動機能の改善

This commit is contained in:
NoriDev 2023-10-12 20:09:55 +09:00
parent 9a80a060c6
commit f2100011aa
45 changed files with 239 additions and 151 deletions

View file

@ -37,6 +37,9 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2023xx](CHANGE
### General
- Feat: 읽지 않은 알림 수를 표시할 수 있음 (misskey-dev/misskey#11982)
- Feat: 햅틱 피드백 개선
- 지원 범위 추가
- 설정을 세부적으로 변경할 수 있음
- Fix: 서버 측에서 테스트 알림을 올바르게 수행할 수 있도록 수정 (misskey-dev/misskey#11982)
### Client

View file

@ -602,9 +602,9 @@ 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."
soundsAndVibrations: "Sounds & Vibrations"
playVibrations: "Play vibrations"
playVibrationsDescription: "This feature is not supported on iOS/iPadOS."
listen: "Listen"
none: "None"
showInPage: "Show in page"
@ -1224,6 +1224,13 @@ additionalPermissionsForFlash: "Allow to add permission to Play"
thisFlashRequiresTheFollowingPermissions: "This Play requires the following permissions"
doYouWantToAllowThisPlayToAccessYourAccount: "Do you want to allow this Play to access your account?"
translateProfile: "Translate profile"
_vibrations:
click: "When an element is clicked"
note: "When a new note is posted on the timeline"
notification: "When a receive the notifications"
chat: "Chat"
chatBg: "Chat (Background)"
system: "System Haptics"
_showingAnimatedImages:
always: "Always animate"
interaction: "Animate on interaction"

12
locales/index.d.ts vendored
View file

@ -606,8 +606,8 @@ export interface Locale {
"sound": string;
"vibrations": string;
"soundsAndVibrations": string;
"playVibrationsOnClick": string;
"playVibrationsOnClickDescription": string;
"playVibrations": string;
"playVibrationsDescription": string;
"listen": string;
"none": string;
"showInPage": string;
@ -1227,6 +1227,14 @@ export interface Locale {
"thisFlashRequiresTheFollowingPermissions": string;
"doYouWantToAllowThisPlayToAccessYourAccount": string;
"translateProfile": string;
"_vibrations": {
"click": string;
"note": string;
"notification": string;
"chat": string;
"chatBg": string;
"system": string;
};
"_showingAnimatedImages": {
"always": string;
"interaction": string;

View file

@ -603,8 +603,8 @@ sounds: "サウンド"
sound: "サウンド"
vibrations: "振動"
soundsAndVibrations: "サウンドと振動"
playVibrationsOnClick: "クリック時の振動再生"
playVibrationsOnClickDescription: "この機能はiOS/iPadOSではサポートされていません。"
playVibrations: "振動再生"
playVibrationsDescription: "この機能はiOS/iPadOSではサポートされていません。"
listen: "聴く"
none: "なし"
showInPage: "ページで表示"
@ -1225,6 +1225,14 @@ thisFlashRequiresTheFollowingPermissions: "このPlayは以下の権限を要求
doYouWantToAllowThisPlayToAccessYourAccount: "このPlayによるアカウントへのアクセスを許可しますか"
translateProfile: "プロフィールを翻訳する"
_vibrations:
click: "要素をクリックしたとき"
note: "タイムラインに新しいノートがあるとき"
notification: "通知を受け取ったとき"
chat: "チャット"
chatBg: "チャット(バックグラウンド)"
system: "システムの触覚"
_showingAnimatedImages:
always: "常に再生"
interaction: "インタラクト時に再生"

View file

@ -604,8 +604,8 @@ sounds: "소리"
sound: "소리"
vibrations: "진동"
soundsAndVibrations: "소리 및 진동"
playVibrationsOnClick: "클릭 시 진동 재생"
playVibrationsOnClickDescription: "이 기능은 iOS/iPadOS에서는 지원되지 않아요."
playVibrations: "진동 재생"
playVibrationsDescription: "이 기능은 iOS/iPadOS에서는 지원되지 않아요."
listen: "듣기"
none: "없음"
showInPage: "페이지로 보기"
@ -1214,6 +1214,13 @@ additionalPermissionsForFlash: "Play에 대한 추가 권한"
thisFlashRequiresTheFollowingPermissions: "이 Play는 다음 권한을 요구해요"
doYouWantToAllowThisPlayToAccessYourAccount: "이 Play가 계정에 접근하도록 허용할까요?"
translateProfile: "프로필 번역하기"
_vibrations:
click: "요소를 클릭했을 때"
note: "타임라인에 새 노트가 올라왔을 때"
notification: "알림을 수신했을 때"
chat: "대화"
chatBg: "대화 (백그라운드)"
system: "시스템 햅틱"
_showingAnimatedImages:
always: "항상 움직임"
interaction: "건드리면 움직임"

View file

@ -20,6 +20,7 @@ import { mainRouter } from '@/router.js';
import { initializeSw } from '@/scripts/initialize-sw.js';
import { deckStore } from '@/ui/deck/deck-store.js';
import { userName } from '@/filters/user.js';
import { vibrate } from '@/scripts/vibrate.js';
export async function mainBoot() {
const { isClientUpdated } = await common(() => createApp(
@ -264,6 +265,7 @@ export async function mainBoot() {
main.on('unreadMessagingMessage', () => {
updateAccount({ hasUnreadMessagingMessage: true });
sound.play('chatBg');
vibrate(ColdDeviceStorage.get('vibrateChatBg') ? [50, 40] : '');
});
main.on('readAllAntennas', () => {

View file

@ -35,6 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { nextTick, onMounted } from 'vue';
import { vibrate } from '@/scripts/vibrate.js';
import {ColdDeviceStorage} from "@/store.js";
const props = defineProps<{
type?: 'button' | 'submit' | 'reset';
@ -100,7 +101,7 @@ function onMousedown(evt: MouseEvent): void {
const scale = calcCircleScale(target.clientWidth, target.clientHeight, circleCenterX, circleCenterY);
vibrate(10);
vibrate(ColdDeviceStorage.get('vibrateSystem') ? 10 : '');
window.setTimeout(() => {
ripple.style.transform = 'scale(' + (scale / 2) + ')';

View file

@ -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" v-vibrate="5" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
<button v-if="omitted" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
</button>
</div>
@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onMounted, onUnmounted, ref, shallowRef, watch } from 'vue';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { i18n } from '@/i18n.js';
const props = withDefaults(defineProps<{

View file

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button
v-for="emoji in searchResultCustom"
:key="emoji.name"
v-vibrate="50"
v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 50 : ''"
class="_button item"
:title="emoji.name"
tabindex="0"
@ -107,7 +107,7 @@ import * as os from '@/os.js';
import { isTouchUsing } from '@/scripts/touch.js';
import { deviceKind } from '@/scripts/device-kind.js';
import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { customEmojiCategories, customEmojis, customEmojisMap } from '@/custom-emojis.js';
import { $i } from '@/account.js';

View file

@ -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 v-vibrate="5" :class="[$style.header, { [$style.opened]: opened, [$style.inactive]: inactive || isArchived }]" class="_button" role="button" data-cy-folder-header @click="toggle">
<div v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -52,7 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { nextTick, onMounted } from 'vue';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
const props = withDefaults(defineProps<{
defaultOpen?: boolean;

View file

@ -47,6 +47,7 @@ import { $i } from '@/account.js';
import { userName } from '@/filters/user.js';
import { globalEvents } from '@/events.js';
import { vibrate } from '@/scripts/vibrate.js';
import {ColdDeviceStorage} from "@/store.js";
let showFollowButton = $ref(false);
@ -109,7 +110,7 @@ async function onClick() {
await os.api('following/create', {
userId: props.user.id,
});
vibrate([30, 40, 100]);
vibrate(ColdDeviceStorage.get('vibrateSystem') ? [30, 40, 100] : '');
hasPendingFollowRequestFromYou = true;
claimAchievement('following1');

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div role="menu">
<div
ref="itemsEl" v-hotkey="keymap" v-vibrate="5"
ref="itemsEl" v-hotkey="keymap" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
class="_popup _shadow"
:class="[$style.root, { [$style.center]: align === 'center', [$style.asDrawer]: asDrawer }]"
:style="{ width: (width && !asDrawer) ? width + 'px' : '', maxHeight: maxHeight ? maxHeight + 'px' : '' }"
@ -74,6 +74,7 @@ const childrenCache = new WeakMap<MenuParent, MenuItem[]>();
</script>
<script lang="ts" setup>
import {ColdDeviceStorage} from "@/store.js";
const XChild = defineAsyncComponent(() => import('./MkMenu.child.vue'));
const props = defineProps<{

View file

@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
v-show="!isDeleted"
ref="el"
v-hotkey="keymap"
v-vibrate="5"
v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
:class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover, [$style.radius]: defaultStore.state.showGapBetweenNotesInTimeline && mainRouter.currentRoute.value.name === 'my-notifications' }]"
:tabindex="!isDeleted ? '-1' : undefined"
>
@ -99,13 +99,13 @@ 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) || (appearNote.files.length > 0 && defaultStore.state.allMediaNoteCollapse)) && collapsed" v-vibrate="5" :class="$style.collapsed" class="_button" @click="collapsed = false">
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || (appearNote.files.length > 0 && defaultStore.state.allMediaNoteCollapse)) && collapsed" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.collapsed" class="_button" @click="collapsed = false">
<span :class="$style.collapsedLabel">
{{ i18n.ts.showMore }}
<span v-if="appearNote.files.length > 0" :class="$style.label">({{ collapseLabel }})</span>
</span>
</button>
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.showLess" class="_button" @click="collapsed = true">
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
</button>
</div>
@ -119,14 +119,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</MkReactionsViewer>
<footer :class="$style.footer">
<button v-vibrate="5" v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [30, 30, 60] : ''"
v-tooltip="i18n.ts.renote"
:class="$style.footerButton"
class="_button"
@ -138,26 +138,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-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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" v-vibrate="[30, 50, 50]" :class="$style.footerButton" class="_button" @click="undoReact(appearNote)">
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
<button ref="menuButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
<i class="ti ti-dots"></i>
</button>
</footer>
@ -194,7 +194,7 @@ import { focusPrev, focusNext } from '@/scripts/focus.js';
import { checkWordMute } from '@/scripts/check-word-mute.js';
import { userPage } from '@/filters/user.js';
import * as os from '@/os.js';
import { defaultStore, noteViewInterruptors } from '@/store.js';
import {ColdDeviceStorage, defaultStore, noteViewInterruptors} from '@/store.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
import { $i } from '@/account.js';

View file

@ -132,14 +132,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkA>
</div>
<MkReactionsViewer ref="reactionsViewer" :note="appearNote"/>
<button v-vibrate="5" v-tooltip="i18n.ts.reply" class="_button" :class="$style.noteFooterButton" @click="reply()">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [30, 30, 60] : ''"
v-tooltip="i18n.ts.renote"
class="_button"
:class="$style.noteFooterButton"
@ -151,23 +151,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-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.noteFooterButton" class="_button" @mousedown="heartReact()">
<button v-if="appearNote.myReaction == null" ref="heartReactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
<button v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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" v-vibrate="[30, 50, 50]" :class="[$style.noteFooterButton, $style.reacted]" class="_button" @click="undoReact(appearNote)">
<button v-if="appearNote.myReaction != null && appearNote.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.noteFooterButton" @mousedown="quote()">
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip="i18n.ts.clip" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" v-tooltip="i18n.ts.clip" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
<i class="ti ti-paperclip"></i>
</button>
<button ref="menuButton" v-vibrate="5" v-tooltip="i18n.ts.more" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
<button ref="menuButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" v-tooltip="i18n.ts.more" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
<i class="ti ti-dots"></i>
</button>
</footer>
@ -271,7 +271,7 @@ import { checkWordMute } from '@/scripts/check-word-mute.js';
import { userPage } from '@/filters/user.js';
import { notePage } from '@/filters/note.js';
import * as os from '@/os.js';
import { defaultStore, noteViewInterruptors } from '@/store.js';
import { ColdDeviceStorage, defaultStore, noteViewInterruptors } from '@/store.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
import { $i } from '@/account.js';

View file

@ -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" v-vibrate="5" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
<button v-if="omitted" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
</button>
</div>
@ -15,6 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onMounted, onUnmounted } from 'vue';
import { i18n } from '@/i18n.js';
import { ColdDeviceStorage } from '@/store.js';
const props = withDefaults(defineProps<{
maxHeight?: number;

View file

@ -119,7 +119,7 @@ import { formatTimeString } from '@/scripts/format-time-string.js';
import { Autocomplete } from '@/scripts/autocomplete.js';
import * as os from '@/os.js';
import { selectFiles } from '@/scripts/select-file.js';
import { defaultStore, notePostInterruptors, postFormActions } from '@/store.js';
import {ColdDeviceStorage, defaultStore, notePostInterruptors, postFormActions} from '@/store.js';
import MkInfo from '@/components/MkInfo.vue';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
@ -851,7 +851,7 @@ async function post(ev?: MouseEvent) {
text: err.message + '\n' + (err as any).id,
});
});
vibrate([10, 20, 10, 20, 10, 20, 60]);
vibrate(ColdDeviceStorage.get('vibrateSystem') ? [10, 20, 10, 20, 10, 20, 60] : '');
}
function cancel() {

View file

@ -139,7 +139,7 @@ import { formatTimeString } from '@/scripts/format-time-string.js';
import { Autocomplete } from '@/scripts/autocomplete.js';
import * as os from '@/os.js';
import { selectFiles } from '@/scripts/select-file.js';
import { defaultStore, notePostInterruptors, postFormActions } from '@/store.js';
import {ColdDeviceStorage, defaultStore, notePostInterruptors, postFormActions} from '@/store.js';
import MkInfo from '@/components/MkInfo.vue';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
@ -872,7 +872,7 @@ async function post(ev?: MouseEvent) {
text: err.message + '\n' + (err as any).id,
});
});
vibrate([10, 20, 10, 20, 10, 20, 60]);
vibrate(ColdDeviceStorage.get('vibrateSystem') ? [10, 20, 10, 20, 10, 20, 60] : '');
}
function cancel() {

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div
v-adaptive-border
v-vibrate="5"
v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
:class="[$style.root, { [$style.disabled]: disabled, [$style.checked]: checked }]"
:aria-checked="checked"
:aria-disabled="disabled"
@ -26,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { } from 'vue';
import { ColdDeviceStorage } from '@/store.js';
const props = defineProps<{
modelValue: any;

View file

@ -25,6 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { computed, defineAsyncComponent, onMounted, onUnmounted, ref, watch, shallowRef } from 'vue';
import * as os from '@/os.js';
import { vibrate } from '@/scripts/vibrate.js';
import {ColdDeviceStorage} from "@/store.js";
const props = withDefaults(defineProps<{
modelValue: number;
@ -101,7 +102,7 @@ const steps = computed(() => {
});
const onMousedown = (ev: MouseEvent | TouchEvent) => {
vibrate(10);
vibrate(ColdDeviceStorage.get('vibrateSystem') ? 10 : '');
ev.preventDefault();

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button
ref="buttonEl"
v-ripple="canToggle"
v-vibrate="[10, 30, 40]"
v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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()"
@ -27,7 +27,7 @@ import { useTooltip } from '@/scripts/use-tooltip.js';
import { $i } from '@/account.js';
import MkReactionEffect from '@/components/MkReactionEffect.vue';
import { claimAchievement } from '@/scripts/achievements.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { customEmojis } from '@/custom-emojis.js';

View file

@ -36,13 +36,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || note.files.length > 0 || note.poll || defaultStore.state.allMediaNoteCollapse) && collapsed" v-vibrate="5" :class="$style.fade" class="_button" @click="collapsed = false;">
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || note.files.length > 0 || note.poll || defaultStore.state.allMediaNoteCollapse) && collapsed" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.fade" class="_button" @click="collapsed = false;">
<span :class="$style.fadeLabel">
{{ i18n.ts.showMore }}
<span v-if="note.files.length > 0" :class="$style.label">({{ collapseLabel }})</span>
</span>
</button>
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || note.files.length > 0 || note.poll || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true;">
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || note.files.length > 0 || note.poll || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.showLess" class="_button" @click="collapsed = true;">
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
</button>
<div v-if="showSubNoteFooterButton">
@ -54,14 +54,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</MkReactionsViewer>
<footer :class="$style.footer">
<button v-vibrate="5" v-tooltip="i18n.ts.reply" :class="$style.footerButton" class="_button" @click="reply()">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [30, 50, 60] : ''"
v-tooltip="i18n.ts.renote"
:class="$style.footerButton"
class="_button"
@ -73,26 +73,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-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.like" :class="$style.footerButton" class="_button" @mousedown="heartReact()">
<button v-if="note.myReaction == null" ref="heartReactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [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.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
<button v-if="note.reactionAcceptance !== 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [30, 50, 50] : ''" v-tooltip="i18n.ts.reaction" :class="$style.footerButton" class="_button" @mousedown="react()">
<i v-if="note.myReaction == null" class="ti ti-mood-plus"></i>
<i v-else class="ti ti-mood-edit"></i>
</button>
<button v-if="note.myReaction != null && note.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="[30, 50, 50]" :class="$style.footerButton" class="_button" @click="undoReact(note)">
<button v-if="note.myReaction != null && note.reactionAcceptance == 'likeOnly'" ref="reactButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? [30, 50, 50] : ''" :class="$style.footerButton" class="_button" @click="undoReact(note)">
<i class="ti ti-heart-minus"></i>
</button>
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="5" v-tooltip="i18n.ts.quote" class="_button" :class="$style.footerButton" @mousedown="quote()">
<button v-if="canRenote && defaultStore.state.renoteQuoteButtonSeparation" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip="i18n.ts.clip" :class="$style.footerButton" class="_button" @mousedown="clip()">
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
<button ref="menuButton" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" v-tooltip="i18n.ts.more" :class="$style.footerButton" class="_button" @mousedown="menu()">
<i class="ti ti-dots"></i>
</button>
</footer>
@ -112,7 +112,7 @@ import MkReactionsViewer from '@/components/MkReactionsViewer.vue';
import { i18n } from '@/i18n.js';
import { $i } from '@/account.js';
import { shouldCollapsed, shouldMfmCollapsed } from '@/scripts/collapsed.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { miLocalStorage } from '@/local-storage.js';
import { instance } from '@/instance.js';
import { notePage } from '@/filters/note.js';

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<span
v-vibrate="5"
v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff"
:class="{
[$style.button]: true,
@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { toRefs, Ref } from 'vue';
import { i18n } from '@/i18n.js';
import { ColdDeviceStorage } from '@/store.js';
const props = withDefaults(defineProps<{
checked: boolean | Ref<boolean>;

View file

@ -18,8 +18,9 @@ import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { $i } from '@/account.js';
import { instance } from '@/instance.js';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { i18n } from '@/i18n.js';
import { vibrate } from '@/scripts/vibrate.js';
const props = withDefaults(defineProps<{
src: string;
@ -63,6 +64,7 @@ const prepend = note => {
if (props.sound) {
sound.play($i && (note.userId === $i.id) ? 'noteMy' : 'note');
vibrate($i && (note.userId === $i.id) ? '' : ColdDeviceStorage.get('vibrateNote') ? [30, 20] : '');
}
};
@ -75,6 +77,7 @@ const prependFilterdMedia = note => {
if (props.sound) {
sound.play($i && (note.userId === $i.id) ? 'noteMy' : 'note');
vibrate($i && (note.userId === $i.id) ? '' : ColdDeviceStorage.get('vibrateNote') ? [30, 20] : '');
}
};

View file

@ -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 v-vibrate="5" class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" :class="$style.avatar" :user="$i"/>
<MkAvatar v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-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>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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"/>
@ -66,7 +66,7 @@ import { miLocalStorage } from '@/local-storage.js';
import { mainRouter } from '@/router.js';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import MkFollowButton from '@/components/MkFollowButton.vue';
let showFollowButton = $ref(false);

View file

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<a v-vibrate="5" :href="to" :class="active ? activeClass : null" @click.prevent="nav" @contextmenu.prevent.stop="onContextmenu">
<a v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :href="to" :class="active ? activeClass : null" @click.prevent="nav" @contextmenu.prevent.stop="onContextmenu">
<slot></slot>
</a>
</template>
@ -16,6 +16,7 @@ import { url } from '@/config.js';
import { popout as popout_ } from '@/scripts/popout.js';
import { i18n } from '@/i18n.js';
import { useRouter } from '@/router.js';
import { ColdDeviceStorage } from '@/store.js';
const props = withDefaults(defineProps<{
to: string;

View file

@ -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-vibrate="5" v-tooltip.noDelay="t.title"
v-for="t in tabs" :ref="(el) => tabRefs[t.key] = (el as HTMLElement)" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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)"
>
@ -54,7 +54,7 @@ export type Tab = {
<script lang="ts" setup>
import { onMounted, onUnmounted, watch, nextTick, shallowRef } from 'vue';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
const props = withDefaults(defineProps<{
tabs?: Tab[];

View file

@ -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 v-vibrate="5" class="_button" :class="[$style.button, $style.goBack]" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" :class="$style.avatar" :user="$i"/>
<MkAvatar v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-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>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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"/>
@ -62,7 +62,7 @@ import { miLocalStorage } from '@/local-storage.js';
import { mainRouter } from '@/router.js';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import MkFollowButton from '@/components/MkFollowButton.vue';
let showFollowButton = $ref(false);

View file

@ -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 v-vibrate="5" class="_button button goBack" @click.stop="goBack" @touchstart="preventDrag"><i class="ti ti-arrow-left"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-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>
<button v-else v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -44,6 +44,7 @@ import MkButton from '@/components/MkButton.vue';
import { globalEvents } from '@/events.js';
import { injectPageMetadata } from '@/scripts/page-metadata.js';
import { deviceKind } from '@/scripts/device-kind.js';
import { ColdDeviceStorage } from '@/store.js';
const MOBILE_THRESHOLD = 500;

View file

@ -69,7 +69,7 @@ import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { i18n } from '@/i18n.js';
import { $i } from '@/account.js';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { vibrate } from '@/scripts/vibrate.js';
import { miLocalStorage } from '@/local-storage.js';
@ -210,7 +210,7 @@ function onDrop(ev: DragEvent): void {
function onMessage(message) {
sound.play('chat');
vibrate([30, 30, 30]);
vibrate(ColdDeviceStorage.get('vibrateChat') ? [30, 30, 30] : '');
const _isBottom = isBottomVisible($$(rootEl).value, 64);

View file

@ -128,6 +128,11 @@ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
'syncDeviceDarkMode',
'plugins',
'vibrate',
'vibrateNote',
'vibrateNotification',
'vibrateChat',
'vibrateChatBg',
'vibrateSystem',
'sound_masterVolume',
'sound_note',
'sound_noteMy',

View file

@ -24,16 +24,22 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton danger @click="reset()"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</MkButton>
<FormSection>
<template #label>{{ i18n.ts.vibrations }}</template>
<template #label>{{ i18n.ts.vibrations }} <span class="_beta">CherryPick</span></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>
<MkSwitch v-model="vibrate" @click="demoVibrate()">{{ i18n.ts.playVibrations }}<template #caption>{{ i18n.ts.playVibrationsDescription }}</template></MkSwitch>
<MkSwitch v-if="vibrate" v-model="vibrateNote">{{ i18n.ts._vibrations.note }}</MkSwitch>
<MkSwitch v-if="vibrate" v-model="vibrateNotification">{{ i18n.ts._vibrations.notification }}</MkSwitch>
<MkSwitch v-if="vibrate" v-model="vibrateChat">{{ i18n.ts._vibrations.chat }}</MkSwitch>
<MkSwitch v-if="vibrate" v-model="vibrateChatBg">{{ i18n.ts._vibrations.chatBg }}</MkSwitch>
<MkSwitch v-if="vibrate" v-model="vibrateSystem" style="margin-top: 10px;">{{ i18n.ts._vibrations.system }}</MkSwitch>
</div>
</FormSection>
</div>
</template>
<script lang="ts" setup>
import { Ref, computed, ref } from 'vue';
import {Ref, computed, ref, watch} from 'vue';
import * as os from "@/os.js";
import XSound from './sounds.sound.vue';
import MkRange from '@/components/MkRange.vue';
import MkButton from '@/components/MkButton.vue';
@ -44,6 +50,7 @@ import { soundConfigStore } from '@/scripts/sound.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { ColdDeviceStorage } from '@/store.js';
import {unisonReload} from "@/scripts/unison-reload.js";
const masterVolume = computed(soundConfigStore.makeGetterSetter('sound_masterVolume'));
@ -60,6 +67,21 @@ const sounds = ref<Record<typeof soundsKeys[number], Ref<any>>>({
});
const vibrate = computed(ColdDeviceStorage.makeGetterSetter('vibrate'));
const vibrateNote = computed(ColdDeviceStorage.makeGetterSetter('vibrateNote'));
const vibrateNotification = computed(ColdDeviceStorage.makeGetterSetter('vibrateNotification'));
const vibrateChat = computed(ColdDeviceStorage.makeGetterSetter('vibrateChat'));
const vibrateChatBg = computed(ColdDeviceStorage.makeGetterSetter('vibrateChatBg'));
const vibrateSystem = computed(ColdDeviceStorage.makeGetterSetter('vibrateSystem'));
async function reloadAsk() {
const { canceled } = await os.confirm({
type: 'info',
text: i18n.ts.reloadToApplySetting,
});
if (canceled) return;
unisonReload();
}
async function updated(type: keyof typeof sounds.value, sound) {
const v = {
@ -83,6 +105,12 @@ function demoVibrate() {
window.navigator.vibrate(100);
}
watch([
vibrateSystem,
], async () => {
await reloadAsk();
});
const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);

View file

@ -576,6 +576,11 @@ export class ColdDeviceStorage {
plugins: [] as Plugin[],
mediaVolume: 0.5,
vibrate: true,
vibrateNote: true,
vibrateNotification: true,
vibrateChat: true,
vibrateChatBg: true,
vibrateSystem: true,
sound_masterVolume: 0.5,
sound_note: { type: 'syuilo/down', volume: 0.5 },
sound_noteMy: { type: 'syuilo/up', volume: 0.5 },

View file

@ -55,8 +55,9 @@ import * as sound from '@/scripts/sound.js';
import { $i } from '@/account.js';
import { useStream } from '@/stream.js';
import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { globalEvents } from '@/events.js';
import { vibrate } from '@/scripts/vibrate.js';
const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue'));
const XUpload = defineAsyncComponent(() => import('./upload.vue'));
@ -83,6 +84,7 @@ function onNotification(notification: Misskey.entities.Notification, isClient =
}
sound.play('notification');
vibrate(ColdDeviceStorage.get('vibrateNotification') ? [20, 30, 30, 30] : '');
}
if ($i) {

View file

@ -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 v-vibrate="5" class="_button" :class="$style.instance" @click="openInstanceMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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)" 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 } : {}">
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="navbarItemDef[item].indicateValue && defaultStore.state.showUnreadNotificationCount" :class="$style.itemIndicateValueIcon"><span>{{ navbarItemDef[item].indicateValue }}</span></span>
@ -31,7 +31,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 v-vibrate="5" :class="$style.item" class="_button" @click="more">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -41,10 +41,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-vibrate="5" class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" class="_button" :class="$style.account" @click="openAccountMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_button" :class="$style.account" @click="openAccountMenu">
<MkAvatar :user="$i" :class="$style.avatar"/><MkAcct :class="$style.acct" class="_nowrap" :user="$i"/>
</button>
</div>
@ -57,7 +57,7 @@ import { openInstanceMenu } from './common';
import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { version } from '@/config.js';

View file

@ -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-vibrate="5" v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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,7 +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-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
v-tooltip.noDelay.right="navbarItemDef[item].title"
class="_button"
:class="[$style.item, { [$style.active]: navbarItemDef[item].active }]"
@ -42,7 +42,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 v-vibrate="5" class="_button" :class="$style.item" @click="more">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -52,10 +52,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-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">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -69,7 +69,7 @@ import { openInstanceMenu } from './common';
import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { version } from '@/config.js';

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="azykntjl">
<div class="body">
<div class="left">
<button v-click-anime v-vibrate="5" class="item _button instance" @click="openInstanceMenu">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-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 } : {}">
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<i class="ti ti-dashboard ti-fw"></i>
<span v-if="controlPanelIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
</MkA>
<button v-click-anime v-vibrate="5" class="item _button" @click="more">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -34,7 +34,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 v-vibrate="5" class="item _button account" @click="openAccountMenu">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="item _button account" @click="openAccountMenu">
<MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/>
</button>
<div class="post" @click="os.post()">
@ -54,7 +54,7 @@ import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar';
import { openAccountMenu as openAccountMenu_, $i } from '@/account.js';
import MkButton from '@/components/MkButton.vue';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { instance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { version } from '@/config.js';

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="npcljfve" :class="{ iconOnly }">
<button v-click-anime v-vibrate="5" class="item _button account" @click="openAccountMenu">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" 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="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="navbarItemDef[item].indicateValue && defaultStore.state.showUnreadNotificationCount" class="itemIndicateValueIcon"><span>{{ navbarItemDef[item].indicateValue }}</span></span>
@ -32,7 +32,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 v-vibrate="5" class="item _button" @click="more">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkA>
<div class="divider"></div>
<div class="about">
<button v-click-anime v-vibrate="5" class="item _button" @click="openInstanceMenu">
<button v-click-anime v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="item _button" @click="openInstanceMenu">
<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
</button>
</div>
@ -60,7 +60,7 @@ import MkButton from '@/components/MkButton.vue';
// import { StickySidebar } from '@/scripts/sticky-sidebar.js';
// import { mainRouter } from '@/router.js';
//import CherryPickLogo from '@assets/client/cherrypick.svg';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { instance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { version } from '@/config.js';

View file

@ -36,30 +36,30 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div :class="$style.sideMenu">
<div :class="$style.sideMenuTop">
<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>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" 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="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 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')">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.navButton" class="_button" @click="mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="$i?.unreadNotificationCount && defaultStore.state.showUnreadNotificationCount" :class="$style.navButtonIndicateValueIcon"><span>{{ $i.unreadNotificationCount > 99 ? '99+' : $i.unreadNotificationCount }}</span></span>
<i v-else 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>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
</div>
<Transition
@ -108,7 +108,7 @@ import { i18n } from '@/i18n.js';
import { mainRouter } from '@/router.js';
import { unisonReload } from '@/scripts/unison-reload.js';
import { deviceKind } from '@/scripts/device-kind.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import XMainColumn from '@/ui/deck/main-column.vue';
import XTlColumn from '@/ui/deck/tl-column.vue';
import XAntennaColumn from '@/ui/deck/antenna-column.vue';

View file

@ -26,26 +26,26 @@ SPDX-License-Identifier: AGPL-3.0-only
<XWidgets/>
</div>
<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 && enableNavButton.includes(<string>mainRouter.currentRoute.value.name)" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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)" 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="isMobile && enablePostButton.includes(<string>mainRouter.currentRoute.value.name)" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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" 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>
<button v-if="!isDesktop && !isMobile" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 }">
<!-- 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')">
<!-- v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="$i?.unreadNotificationCount && defaultStore.state.showUnreadNotificationCount" :class="$style.navButtonIndicateValueIcon"><span>{{ $i.unreadNotificationCount > 99 ? '99+' : $i.unreadNotificationCount }}</span></span>
<i v-else 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> -->
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
<!-- <button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button> -->
</div>
<Transition
@ -113,7 +113,7 @@ import XCommon from '@/ui/_common_/common.vue';
import { instanceName } from '@/config.js';
import XDrawerMenu from '@/ui/friendly/navbar-for-mobile.vue';
import * as os from '@/os.js';
import { defaultStore } from '@/store.js';
import {ColdDeviceStorage, defaultStore} from '@/store.js';
import { i18n } from '@/i18n.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import { mainRouter } from '@/router.js';

View file

@ -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 v-vibrate="5" class="_button" :class="$style.instance" @click="openInstanceMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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)" 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 } : {}">
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="navbarItemDef[item].indicateValue && defaultStore.state.showUnreadNotificationCount" :class="$style.itemIndicateValueIcon"><span>{{ navbarItemDef[item].indicateValue }}</span></span>
@ -31,7 +31,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 v-vibrate="5" :class="$style.item" class="_button" @click="more">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -41,14 +41,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 v-vibrate="5" class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" class="_button" :class="$style.account" @click="openProfile">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_button" :class="$style.account" @click="openProfile">
<MkAvatar :user="$i" :class="$style.avatar"/><MkUserName :class="$style.acct" class="_nowrap" :user="$i"/>
</button>
<button v-vibrate="5" class="_button" :class="$style.drawer" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_button" :class="$style.drawer" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
</div>
</div>
</div>
@ -60,7 +60,7 @@ import { openInstanceMenu } from '@/ui/_common_/common.js';
import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { mainRouter } from '@/router.js';

View file

@ -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-vibrate="5" v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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,7 +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-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''"
v-tooltip.noDelay.right="navbarItemDef[item].title"
class="_button"
:class="[$style.item, { [$style.active]: navbarItemDef[item].active }]"
@ -42,7 +42,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 v-vibrate="5" class="_button" :class="$style.item" @click="more">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -52,17 +52,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-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">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
<button v-if="iconOnly" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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-vibrate="5" v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openProfile">
<button v-else v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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" v-vibrate="5" class="_button" :class="[$style.drawer]" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
<button v-if="!iconOnly" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_button" :class="[$style.drawer]" @click="openAccountMenu"><i class="ti ti-chevron-up"/></button>
</div>
</div>
</div>
@ -75,7 +75,7 @@ import { openInstanceMenu } from '@/ui/_common_/common.js';
import * as os from '@/os.js';
import { navbarItemDef } from '@/navbar.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { mainRouter } from '@/router.js';

View file

@ -22,20 +22,20 @@ SPDX-License-Identifier: AGPL-3.0-only
<XWidgets/>
</div>
<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>
<button v-if="!isDesktop && !isMobile" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 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')">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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">
<span v-if="$i?.unreadNotificationCount && defaultStore.state.showUnreadNotificationCount" :class="$style.navButtonIndicateValueIcon"><span>{{ $i.unreadNotificationCount > 99 ? '99+' : $i.unreadNotificationCount }}</span></span>
<i v-else 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>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
</div>
<Transition
@ -102,7 +102,7 @@ import type MkStickyContainer from '@/components/global/MkStickyContainer.vue';
import { instanceName } from '@/config.js';
import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
import * as os from '@/os.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { navbarItemDef } from '@/navbar.js';
import { i18n } from '@/i18n.js';
import { $i } from '@/account.js';

View file

@ -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" 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>
<button v-if="editMode" v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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="ColdDeviceStorage.get('vibrateSystem') ? 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>
@ -19,7 +19,7 @@ let editMode = $ref(false);
import { } from 'vue';
import XWidgets from '@/components/MkWidgets.vue';
import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
const props = withDefaults(defineProps<{
// null =

View file

@ -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 v-vibrate="5" class="menu _button" @click="showMenu = true">
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 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 v-vibrate="5" class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
<button v-vibrate="5" class="_button" @click="signin()">{{ i18n.ts.login }}</button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" class="_button" @click="signin()">{{ i18n.ts.login }}</button>
</div>
</div>
</Transition>

View file

@ -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-vibrate="5" v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ti ti-home"></i></button>
<button v-vibrate="ColdDeviceStorage.get('vibrateSystem') ? 5 : ''" v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ti ti-home"></i></button>
</div>
</template>
@ -28,6 +28,7 @@ import { mainRouter } from '@/router.js';
import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
import { instanceName, ui } from '@/config.js';
import { i18n } from '@/i18n.js';
import { ColdDeviceStorage } from '@/store.js';
let pageMetadata = $ref<null | ComputedRef<PageMetadata>>();