diff --git a/docs/changelog.md b/docs/changelog.md index 416a0241c9..6167f0e1f8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,4 @@ +- add a toggleable setting to hide follow buttons in a misclickable position - add a toggleable setting to show preview in posting form by default # v20240210 diff --git a/locales/en-US.yml b/locales/en-US.yml index b3df9dbc99..e6d59a0862 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1161,6 +1161,8 @@ noLanguage: "No language" useEmojiCdn: "Get Twemoji from CDN" useEmojiCdnDescription: "Use Twemoji from the JSDelivr CDN instead of the server's assets." showPreviewByDefault: "Show preview in posting form by default" +preventMisclick: "Accidental click prevention" +hideFollowButtons: "Hide follow buttons in a misclickable position" _sensitiveMediaDetection: description: "Reduces the effort of server moderation through automatically recognizing diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index b587051e63..bc0c92900d 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2010,3 +2010,5 @@ noLanguage: "言語なし" moreUrls: "固定するページ" moreUrlsDescription: "左下のヘルプメニューに固定したいページを以下の形式で、改行区切りで入力してください:\n\"表示名\": https://example.com/" showPreviewByDefault: "投稿画面でプレビュー表示をデフォルトでオンにする" +preventMisclick: "誤タップ防止" +hideFollowButtons: "誤タップしやすい位置にあるフォローボタンを隠す" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index b4ba8ce1a5..bfc34ce014 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -2010,3 +2010,5 @@ useEmojiCdnDescription: 使用JSDelivr CDN提供的Twemoji,而不使用儲存 moreUrls: 置頂的頁面 moreUrlsDescription: "請以下列形式輸入欲釘選在左下角幫助選單的頁面,一行一個:\n\"顯示名稱\": https://example.com/" showPreviewByDefault: "自動開啟發文介面中的預覽顯示" +preventMisclick: "預防誤觸" +hideFollowButtons: "隱藏會誤觸的追隨按鈕" diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue index 321d7ac3bf..d9a367c49a 100644 --- a/packages/client/src/components/MkFollowButton.vue +++ b/packages/client/src/components/MkFollowButton.vue @@ -8,7 +8,7 @@ <i :class="icon('ph-dots-three-outline')"></i> </button> <button - v-if="isSignedIn && $i.id != user.id" + v-if="!hideFollowButton && isSignedIn && $i.id != user.id" v-tooltip="full ? null : `${state} ${user.name || user.username}`" class="kpoogebi _button follow-button" :class="{ @@ -81,6 +81,7 @@ const props = withDefaults( full?: boolean; large?: boolean; hideMenu?: boolean; + hideFollowButton?: boolean; }>(), { full: false, @@ -99,6 +100,8 @@ const hasPendingFollowRequestFromYou = ref( const wait = ref(false); const connection = stream.useChannel("main"); +const hideFollowButton = props.hideFollowButton ?? false; + if (props.user.isFollowing == null) { os.api("users/show", { userId: props.user.id, diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue index 668c3dfff0..e196129828 100644 --- a/packages/client/src/components/MkNotification.vue +++ b/packages/client/src/components/MkNotification.vue @@ -215,7 +215,7 @@ class="text" style="opacity: 0.7" >{{ i18n.ts.youGotNewFollower }} - <div v-if="full"> + <div v-if="full && !hideFollowButton"> <MkFollowButton :user="notification.user" :full="true" @@ -304,6 +304,7 @@ const props = withDefaults( const elRef = ref<HTMLElement>(null); const reactionRef = ref(null); +const hideFollowButton = defaultStore.state.hideFollowButtons; const showEmojiReactions = defaultStore.state.enableEmojiReactions || defaultStore.state.showEmojisInReactionNotifications; diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 21c236ca8b..7892cbd5e1 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -285,6 +285,16 @@ </FormSelect> </FormSection> + <FormSection> + <template #label>{{ i18n.ts.preventMisclick }}</template> + <FormSwitch v-model="hideFollowButtons" class="_formBlock" + >{{ i18n.ts.hideFollowButtons + }}<span class="_beta">{{ + i18n.ts.originalFeature + }}</span></FormSwitch + > + </FormSection> + <FormRange v-model="numberOfPageCache" :min="1" @@ -430,6 +440,9 @@ const showPreviewByDefault = computed( const showTimelineReplies = computed( defaultStore.makeGetterSetter("showTimelineReplies"), ); +const hideFollowButtons = computed( + defaultStore.makeGetterSetter("hideFollowButtons"), +); const detectPostLanguage = computed( defaultStore.makeGetterSetter("detectPostLanguage"), ); diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue index 429eedd0a3..442ad6dc6c 100644 --- a/packages/client/src/pages/user/home.vue +++ b/packages/client/src/pages/user/home.vue @@ -400,6 +400,8 @@ import icon from "@/scripts/icon"; const XPhotos = defineAsyncComponent(() => import("./index.photos.vue")); const XActivity = defineAsyncComponent(() => import("./index.activity.vue")); +const hideFollowButton = defaultStore.state.hideFollowButtons; + const emit = defineEmits(["refresh"]); const props = withDefaults( defineProps<{ diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index 9c77c1aa37..c3406d0b98 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -381,6 +381,10 @@ export const defaultStore = markRaw( where: "deviceAccount", default: false, }, + hideFollowButtons: { + where: "device", + default: true, + }, }), );